From 08958c2278b15ebeac8a964f392ebb792e479b61 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:31:40 -0600 Subject: Refactor azalea-protocol (#190) * start updating to 1.21.4 * fix block codegen and stop using block data from burger * rename packet related modules and structs to be simpler * ItemSlot -> ItemStack for more consistency with mojmap * .get() -> .into_packet() * simplify declare_state_packets by removing packet ids * rename read_from and write_into to azalea_read and azalea_write * rename McBufReadable and McBufWritable to AzaleaRead and AzaleaWrite * McBuf -> AzBuf * remove most uses of into_variant * update codegen and use resourcelocation names for packets * implement #[limit(i)] attribute for AzBuf derive macro * fixes for 1.21.4 * fix examples * update some physics code and fix ChatType * remove unused imports in codegen * re-add some things to migrate.py and update +mc version numbers automatically * downgrade to 1.21.3 lol --- Cargo.lock | 76 +- README.md | 2 +- azalea-auth/Cargo.toml | 2 +- azalea-auth/src/game_profile.rs | 6 +- azalea-block/Cargo.toml | 2 +- azalea-block/README.md | 8 +- azalea-block/azalea-block-macros/Cargo.toml | 2 +- azalea-block/src/generated.rs | 430 ++-- azalea-block/src/lib.rs | 14 +- azalea-brigadier/Cargo.toml | 2 +- azalea-brigadier/src/suggestion/mod.rs | 10 +- azalea-brigadier/src/suggestion/suggestions.rs | 28 +- azalea-buf/Cargo.toml | 2 +- azalea-buf/azalea-buf-macros/Cargo.toml | 4 +- azalea-buf/azalea-buf-macros/src/lib.rs | 20 +- azalea-buf/azalea-buf-macros/src/read.rs | 78 +- azalea-buf/azalea-buf-macros/src/write.rs | 36 +- azalea-buf/src/lib.rs | 97 +- azalea-buf/src/read.rs | 195 +- azalea-buf/src/serializable_uuid.rs | 30 +- azalea-buf/src/write.rs | 196 +- azalea-chat/Cargo.toml | 2 +- azalea-chat/src/component.rs | 10 +- azalea-chat/src/numbers.rs | 24 +- azalea-chat/src/style.rs | 4 +- azalea-client/Cargo.toml | 2 +- azalea-client/src/attack.rs | 17 +- azalea-client/src/chat.rs | 50 +- azalea-client/src/chunks.rs | 17 +- azalea-client/src/client.rs | 77 +- azalea-client/src/configuration.rs | 37 +- azalea-client/src/events.rs | 4 +- azalea-client/src/interact.rs | 32 +- azalea-client/src/inventory.rs | 92 +- azalea-client/src/lib.rs | 2 +- azalea-client/src/local_player.rs | 6 +- azalea-client/src/mining.rs | 71 +- azalea-client/src/movement.rs | 49 +- azalea-client/src/packet_handling/configuration.rs | 145 +- azalea-client/src/packet_handling/game.rs | 87 +- azalea-client/src/packet_handling/login.rs | 26 +- azalea-client/src/packet_handling/mod.rs | 4 +- azalea-client/src/ping.rs | 32 +- azalea-client/src/raw_connection.rs | 5 +- azalea-client/src/respawn.rs | 17 +- azalea-core/Cargo.toml | 2 +- azalea-core/src/bitset.rs | 16 +- azalea-core/src/delta.rs | 8 +- azalea-core/src/difficulty.rs | 14 +- azalea-core/src/direction.rs | 6 +- azalea-core/src/game_type.rs | 28 +- azalea-core/src/objectives.rs | 4 +- azalea-core/src/position.rs | 165 +- azalea-core/src/resource_location.rs | 20 +- azalea-crypto/Cargo.toml | 2 +- azalea-crypto/src/signing.rs | 24 +- azalea-entity/Cargo.toml | 6 +- azalea-entity/src/attributes.rs | 6 +- azalea-entity/src/data.rs | 54 +- azalea-entity/src/metadata.rs | 38 +- azalea-entity/src/particle.rs | 27 +- azalea-inventory/Cargo.toml | 6 +- .../azalea-inventory-macros/Cargo.toml | 2 +- .../azalea-inventory-macros/src/menu_enum.rs | 12 +- .../azalea-inventory-macros/src/menu_impl.rs | 16 +- azalea-inventory/src/components.rs | 326 +-- azalea-inventory/src/item/mod.rs | 4 +- azalea-inventory/src/lib.rs | 10 +- azalea-inventory/src/operations.rs | 28 +- azalea-inventory/src/slot.rs | 122 +- azalea-language/Cargo.toml | 2 +- azalea-physics/Cargo.toml | 2 +- azalea-physics/src/clip.rs | 37 +- azalea-physics/src/collision/blocks.rs | 2551 ++++++++++---------- azalea-physics/src/collision/mod.rs | 12 +- azalea-physics/src/collision/shape.rs | 2 +- azalea-physics/src/lib.rs | 16 +- azalea-protocol/Cargo.toml | 2 +- azalea-protocol/README.md | 2 +- azalea-protocol/azalea-protocol-macros/Cargo.toml | 2 +- azalea-protocol/azalea-protocol-macros/src/lib.rs | 287 ++- azalea-protocol/examples/handshake_proxy.rs | 46 +- azalea-protocol/src/common/client_information.rs | 187 ++ azalea-protocol/src/common/mod.rs | 4 + azalea-protocol/src/common/server_links.rs | 28 + azalea-protocol/src/connect.rs | 87 +- azalea-protocol/src/lib.rs | 21 +- azalea-protocol/src/packets/common.rs | 4 +- .../src/packets/config/c_cookie_request.rs | 8 + .../src/packets/config/c_custom_payload.rs | 10 + .../src/packets/config/c_custom_report_details.rs | 9 + azalea-protocol/src/packets/config/c_disconnect.rs | 8 + .../src/packets/config/c_finish_configuration.rs | 5 + azalea-protocol/src/packets/config/c_keep_alive.rs | 7 + azalea-protocol/src/packets/config/c_ping.rs | 7 + .../src/packets/config/c_registry_data.rs | 12 + azalea-protocol/src/packets/config/c_reset_chat.rs | 5 + .../src/packets/config/c_resource_pack.rs | 11 + .../src/packets/config/c_resource_pack_pop.rs | 8 + .../src/packets/config/c_resource_pack_push.rs | 13 + .../src/packets/config/c_select_known_packs.rs | 9 + .../src/packets/config/c_server_links.rs | 9 + .../src/packets/config/c_store_cookie.rs | 9 + azalea-protocol/src/packets/config/c_transfer.rs | 9 + .../packets/config/c_update_enabled_features.rs | 8 + .../src/packets/config/c_update_tags.rs | 74 + azalea-protocol/src/packets/config/mod.rs | 36 + .../src/packets/config/s_client_information.rs | 9 + .../src/packets/config/s_cookie_response.rs | 9 + .../src/packets/config/s_custom_payload.rs | 10 + .../src/packets/config/s_finish_configuration.rs | 5 + azalea-protocol/src/packets/config/s_keep_alive.rs | 7 + azalea-protocol/src/packets/config/s_pong.rs | 7 + .../src/packets/config/s_resource_pack.rs | 20 + .../src/packets/config/s_select_known_packs.rs | 14 + .../clientbound_cookie_request_packet.rs | 8 - .../clientbound_custom_payload_packet.rs | 10 - .../configuration/clientbound_disconnect_packet.rs | 8 - .../clientbound_finish_configuration_packet.rs | 5 - .../configuration/clientbound_keep_alive_packet.rs | 7 - .../configuration/clientbound_ping_packet.rs | 7 - .../clientbound_registry_data_packet.rs | 12 - .../configuration/clientbound_reset_chat_packet.rs | 5 - .../clientbound_resource_pack_packet.rs | 11 - .../clientbound_resource_pack_pop_packet.rs | 8 - .../clientbound_resource_pack_push_packet.rs | 13 - .../clientbound_select_known_packs_packet.rs | 9 - .../clientbound_store_cookie_packet.rs | 9 - .../configuration/clientbound_transfer_packet.rs | 9 - .../clientbound_update_enabled_features_packet.rs | 8 - .../clientbound_update_tags_packet.rs | 74 - azalea-protocol/src/packets/configuration/mod.rs | 56 - .../serverbound_client_information_packet.rs | 193 -- .../serverbound_cookie_response_packet.rs | 9 - .../serverbound_custom_payload_packet.rs | 10 - .../serverbound_finish_configuration_packet.rs | 5 - .../configuration/serverbound_keep_alive_packet.rs | 7 - .../configuration/serverbound_pong_packet.rs | 7 - .../serverbound_resource_pack_packet.rs | 20 - .../serverbound_select_known_packs_packet.rs | 14 - azalea-protocol/src/packets/game/c_add_entity.rs | 37 + .../src/packets/game/c_add_experience_orb.rs | 12 + azalea-protocol/src/packets/game/c_add_player.rs | 27 + azalea-protocol/src/packets/game/c_animate.rs | 21 + azalea-protocol/src/packets/game/c_award_stats.rs | 23 + .../src/packets/game/c_block_changed_ack.rs | 8 + .../src/packets/game/c_block_destruction.rs | 13 + .../src/packets/game/c_block_entity_data.rs | 11 + azalea-protocol/src/packets/game/c_block_event.rs | 12 + azalea-protocol/src/packets/game/c_block_update.rs | 10 + azalea-protocol/src/packets/game/c_boss_event.rs | 143 ++ .../src/packets/game/c_bundle_delimiter.rs | 5 + .../src/packets/game/c_change_difficulty.rs | 9 + azalea-protocol/src/packets/game/c_chat_preview.rs | 9 + .../src/packets/game/c_chunk_batch_finished.rs | 8 + .../src/packets/game/c_chunk_batch_start.rs | 5 + .../src/packets/game/c_chunks_biomes.rs | 14 + azalea-protocol/src/packets/game/c_clear_titles.rs | 7 + .../src/packets/game/c_command_suggestions.rs | 37 + azalea-protocol/src/packets/game/c_commands.rs | 378 +++ .../src/packets/game/c_container_close.rs | 7 + .../src/packets/game/c_container_set_content.rs | 12 + .../src/packets/game/c_container_set_data.rs | 9 + .../src/packets/game/c_container_set_slot.rs | 12 + .../src/packets/game/c_cookie_request.rs | 8 + azalea-protocol/src/packets/game/c_cooldown.rs | 9 + .../src/packets/game/c_custom_chat_completions.rs | 15 + .../src/packets/game/c_custom_payload.rs | 10 + .../src/packets/game/c_custom_report_details.rs | 14 + azalea-protocol/src/packets/game/c_custom_sound.rs | 28 + azalea-protocol/src/packets/game/c_damage_event.rs | 35 + azalea-protocol/src/packets/game/c_debug_sample.rs | 10 + azalea-protocol/src/packets/game/c_delete_chat.rs | 9 + azalea-protocol/src/packets/game/c_disconnect.rs | 8 + .../src/packets/game/c_disguised_chat.rs | 42 + azalea-protocol/src/packets/game/c_entity_event.rs | 8 + .../src/packets/game/c_entity_position_sync.rs | 19 + azalea-protocol/src/packets/game/c_explode.rs | 164 ++ .../src/packets/game/c_forget_level_chunk.rs | 8 + azalea-protocol/src/packets/game/c_game_event.rs | 26 + .../src/packets/game/c_horse_screen_open.rs | 10 + .../src/packets/game/c_hurt_animation.rs | 9 + .../src/packets/game/c_initialize_border.rs | 18 + azalea-protocol/src/packets/game/c_keep_alive.rs | 7 + .../src/packets/game/c_level_chunk_with_light.rs | 65 + azalea-protocol/src/packets/game/c_level_event.rs | 11 + .../src/packets/game/c_level_particles.rs | 39 + azalea-protocol/src/packets/game/c_light_update.rs | 22 + azalea-protocol/src/packets/game/c_login.rs | 27 + .../src/packets/game/c_map_item_data.rs | 88 + .../src/packets/game/c_merchant_offers.rs | 30 + .../src/packets/game/c_move_entity_pos.rs | 11 + .../src/packets/game/c_move_entity_pos_rot.rs | 14 + .../src/packets/game/c_move_entity_rot.rs | 11 + .../packets/game/c_move_minecart_along_track.rs | 19 + azalea-protocol/src/packets/game/c_move_vehicle.rs | 11 + azalea-protocol/src/packets/game/c_open_book.rs | 9 + azalea-protocol/src/packets/game/c_open_screen.rs | 11 + .../src/packets/game/c_open_sign_editor.rs | 9 + azalea-protocol/src/packets/game/c_ping.rs | 7 + .../src/packets/game/c_place_ghost_recipe.rs | 9 + .../src/packets/game/c_player_abilities.rs | 53 + azalea-protocol/src/packets/game/c_player_chat.rs | 160 ++ .../src/packets/game/c_player_chat_header.rs | 10 + .../src/packets/game/c_player_combat_end.rs | 9 + .../src/packets/game/c_player_combat_enter.rs | 6 + .../src/packets/game/c_player_combat_kill.rs | 11 + .../src/packets/game/c_player_info_remove.rs | 8 + .../src/packets/game/c_player_info_update.rs | 326 +++ .../src/packets/game/c_player_look_at.rs | 24 + .../src/packets/game/c_player_position.rs | 61 + .../src/packets/game/c_player_rotation.rs | 8 + .../src/packets/game/c_pong_response.rs | 7 + .../src/packets/game/c_projectile_power.rs | 8 + .../src/packets/game/c_recipe_book_add.rs | 79 + .../src/packets/game/c_recipe_book_remove.rs | 12 + .../src/packets/game/c_recipe_book_settings.rs | 22 + .../src/packets/game/c_remove_entities.rs | 8 + .../src/packets/game/c_remove_mob_effect.rs | 9 + azalea-protocol/src/packets/game/c_reset_score.rs | 8 + .../src/packets/game/c_resource_pack_pop.rs | 8 + .../src/packets/game/c_resource_pack_push.rs | 13 + azalea-protocol/src/packets/game/c_respawn.rs | 10 + azalea-protocol/src/packets/game/c_rotate_head.rs | 9 + .../src/packets/game/c_section_blocks_update.rs | 43 + .../src/packets/game/c_select_advancements_tab.rs | 8 + azalea-protocol/src/packets/game/c_server_data.rs | 9 + azalea-protocol/src/packets/game/c_server_links.rs | 9 + .../src/packets/game/c_set_action_bar_text.rs | 8 + .../src/packets/game/c_set_border_center.rs | 8 + .../src/packets/game/c_set_border_lerp_size.rs | 10 + .../src/packets/game/c_set_border_size.rs | 7 + .../src/packets/game/c_set_border_warning_delay.rs | 8 + .../packets/game/c_set_border_warning_distance.rs | 8 + azalea-protocol/src/packets/game/c_set_camera.rs | 8 + .../src/packets/game/c_set_chunk_cache_center.rs | 10 + .../src/packets/game/c_set_chunk_cache_radius.rs | 8 + .../src/packets/game/c_set_cursor_item.rs | 8 + .../packets/game/c_set_default_spawn_position.rs | 9 + .../src/packets/game/c_set_display_chat_preview.rs | 7 + .../src/packets/game/c_set_display_objective.rs | 31 + .../src/packets/game/c_set_entity_data.rs | 10 + .../src/packets/game/c_set_entity_link.rs | 8 + .../src/packets/game/c_set_entity_motion.rs | 11 + .../src/packets/game/c_set_equipment.rs | 81 + .../src/packets/game/c_set_experience.rs | 11 + azalea-protocol/src/packets/game/c_set_health.rs | 10 + .../src/packets/game/c_set_held_slot.rs | 7 + .../src/packets/game/c_set_objective.rs | 82 + .../src/packets/game/c_set_passengers.rs | 10 + .../src/packets/game/c_set_player_inventory.rs | 10 + .../src/packets/game/c_set_player_team.rs | 74 + azalea-protocol/src/packets/game/c_set_score.rs | 13 + .../src/packets/game/c_set_simulation_distance.rs | 8 + .../src/packets/game/c_set_subtitle_text.rs | 8 + azalea-protocol/src/packets/game/c_set_time.rs | 9 + .../src/packets/game/c_set_title_text.rs | 8 + .../src/packets/game/c_set_titles_animation.rs | 9 + azalea-protocol/src/packets/game/c_sound.rs | 29 + azalea-protocol/src/packets/game/c_sound_entity.rs | 27 + .../src/packets/game/c_start_configuration.rs | 5 + azalea-protocol/src/packets/game/c_stop_sound.rs | 51 + azalea-protocol/src/packets/game/c_store_cookie.rs | 9 + azalea-protocol/src/packets/game/c_system_chat.rs | 45 + azalea-protocol/src/packets/game/c_tab_list.rs | 28 + azalea-protocol/src/packets/game/c_tag_query.rs | 10 + .../src/packets/game/c_take_item_entity.rs | 12 + .../src/packets/game/c_teleport_entity.rs | 13 + .../src/packets/game/c_ticking_state.rs | 8 + azalea-protocol/src/packets/game/c_ticking_step.rs | 8 + azalea-protocol/src/packets/game/c_transfer.rs | 9 + .../src/packets/game/c_update_advancements.rs | 205 ++ .../src/packets/game/c_update_attributes.rs | 18 + .../src/packets/game/c_update_enabled_features.rs | 8 + .../src/packets/game/c_update_mob_effect.rs | 15 + .../src/packets/game/c_update_recipes.rs | 74 + azalea-protocol/src/packets/game/c_update_tags.rs | 74 + .../packets/game/clientbound_add_entity_packet.rs | 37 - .../game/clientbound_add_experience_orb_packet.rs | 12 - .../packets/game/clientbound_add_player_packet.rs | 27 - .../src/packets/game/clientbound_animate_packet.rs | 21 - .../packets/game/clientbound_award_stats_packet.rs | 23 - .../game/clientbound_block_changed_ack_packet.rs | 8 - .../game/clientbound_block_destruction_packet.rs | 13 - .../game/clientbound_block_entity_data_packet.rs | 11 - .../packets/game/clientbound_block_event_packet.rs | 12 - .../game/clientbound_block_update_packet.rs | 10 - .../packets/game/clientbound_boss_event_packet.rs | 145 -- .../src/packets/game/clientbound_bundle_packet.rs | 5 - .../game/clientbound_change_difficulty_packet.rs | 9 - .../game/clientbound_chat_preview_packet.rs | 9 - .../clientbound_chunk_batch_finished_packet.rs | 8 - .../game/clientbound_chunk_batch_start_packet.rs | 5 - .../game/clientbound_chunks_biomes_packet.rs | 14 - .../game/clientbound_clear_titles_packet.rs | 7 - .../game/clientbound_command_suggestions_packet.rs | 37 - .../packets/game/clientbound_commands_packet.rs | 380 --- .../game/clientbound_container_close_packet.rs | 7 - .../clientbound_container_set_content_packet.rs | 12 - .../game/clientbound_container_set_data_packet.rs | 9 - .../game/clientbound_container_set_slot_packet.rs | 12 - .../game/clientbound_cookie_request_packet.rs | 8 - .../packets/game/clientbound_cooldown_packet.rs | 9 - .../clientbound_custom_chat_completions_packet.rs | 15 - .../game/clientbound_custom_payload_packet.rs | 10 - .../clientbound_custom_report_details_packet.rs | 14 - .../game/clientbound_custom_sound_packet.rs | 28 - .../game/clientbound_damage_event_packet.rs | 35 - .../game/clientbound_debug_sample_packet.rs | 10 - .../packets/game/clientbound_delete_chat_packet.rs | 9 - .../packets/game/clientbound_disconnect_packet.rs | 8 - .../game/clientbound_disguised_chat_packet.rs | 42 - .../game/clientbound_entity_event_packet.rs | 8 - .../clientbound_entity_position_sync_packet.rs | 19 - .../src/packets/game/clientbound_explode_packet.rs | 166 -- .../game/clientbound_forget_level_chunk_packet.rs | 8 - .../packets/game/clientbound_game_event_packet.rs | 26 - .../game/clientbound_horse_screen_open_packet.rs | 10 - .../game/clientbound_hurt_animation_packet.rs | 9 - .../game/clientbound_initialize_border_packet.rs | 18 - .../packets/game/clientbound_keep_alive_packet.rs | 7 - .../clientbound_level_chunk_with_light_packet.rs | 66 - .../packets/game/clientbound_level_event_packet.rs | 11 - .../game/clientbound_level_particles_packet.rs | 39 - .../game/clientbound_light_update_packet.rs | 22 - .../src/packets/game/clientbound_login_packet.rs | 27 - .../game/clientbound_map_item_data_packet.rs | 88 - .../game/clientbound_merchant_offers_packet.rs | 30 - .../game/clientbound_move_entity_pos_packet.rs | 11 - .../game/clientbound_move_entity_pos_rot_packet.rs | 14 - .../game/clientbound_move_entity_rot_packet.rs | 11 - .../game/clientbound_move_minecart_packet.rs | 19 - .../game/clientbound_move_vehicle_packet.rs | 11 - .../packets/game/clientbound_open_book_packet.rs | 9 - .../packets/game/clientbound_open_screen_packet.rs | 11 - .../game/clientbound_open_sign_editor_packet.rs | 9 - .../src/packets/game/clientbound_ping_packet.rs | 7 - .../game/clientbound_place_ghost_recipe_packet.rs | 9 - .../game/clientbound_player_abilities_packet.rs | 53 - .../game/clientbound_player_chat_header_packet.rs | 10 - .../packets/game/clientbound_player_chat_packet.rs | 202 -- .../game/clientbound_player_combat_end_packet.rs | 9 - .../game/clientbound_player_combat_enter_packet.rs | 6 - .../game/clientbound_player_combat_kill_packet.rs | 11 - .../game/clientbound_player_info_remove_packet.rs | 8 - .../game/clientbound_player_info_update_packet.rs | 313 --- .../game/clientbound_player_look_at_packet.rs | 24 - .../game/clientbound_player_position_packet.rs | 61 - .../game/clientbound_player_rotation_packet.rs | 8 - .../game/clientbound_pong_response_packet.rs | 7 - .../game/clientbound_projectile_power_packet.rs | 8 - .../game/clientbound_recipe_book_add_packet.rs | 79 - .../game/clientbound_recipe_book_remove_packet.rs | 15 - .../clientbound_recipe_book_settings_packet.rs | 22 - .../game/clientbound_remove_entities_packet.rs | 8 - .../game/clientbound_remove_mob_effect_packet.rs | 9 - .../packets/game/clientbound_reset_score_packet.rs | 8 - .../game/clientbound_resource_pack_pop_packet.rs | 8 - .../game/clientbound_resource_pack_push_packet.rs | 13 - .../src/packets/game/clientbound_respawn_packet.rs | 10 - .../packets/game/clientbound_rotate_head_packet.rs | 9 - .../clientbound_section_blocks_update_packet.rs | 45 - .../clientbound_select_advancements_tab_packet.rs | 8 - .../packets/game/clientbound_server_data_packet.rs | 9 - .../game/clientbound_server_links_packet.rs | 34 - .../game/clientbound_set_action_bar_text_packet.rs | 8 - .../game/clientbound_set_border_center_packet.rs | 8 - .../clientbound_set_border_lerp_size_packet.rs | 10 - .../game/clientbound_set_border_size_packet.rs | 7 - .../clientbound_set_border_warning_delay_packet.rs | 8 - ...ientbound_set_border_warning_distance_packet.rs | 8 - .../packets/game/clientbound_set_camera_packet.rs | 8 - .../clientbound_set_chunk_cache_center_packet.rs | 10 - .../clientbound_set_chunk_cache_radius_packet.rs | 8 - .../game/clientbound_set_cursor_item_packet.rs | 8 - ...lientbound_set_default_spawn_position_packet.rs | 9 - .../clientbound_set_display_chat_preview_packet.rs | 7 - .../clientbound_set_display_objective_packet.rs | 31 - .../game/clientbound_set_entity_data_packet.rs | 10 - .../game/clientbound_set_entity_link_packet.rs | 8 - .../game/clientbound_set_entity_motion_packet.rs | 11 - .../game/clientbound_set_equipment_packet.rs | 81 - .../game/clientbound_set_experience_packet.rs | 11 - .../packets/game/clientbound_set_health_packet.rs | 10 - .../game/clientbound_set_held_slot_packet.rs | 7 - .../game/clientbound_set_objective_packet.rs | 82 - .../game/clientbound_set_passengers_packet.rs | 10 - .../clientbound_set_player_inventory_packet.rs | 10 - .../game/clientbound_set_player_team_packet.rs | 74 - .../packets/game/clientbound_set_score_packet.rs | 13 - .../clientbound_set_simulation_distance_packet.rs | 8 - .../game/clientbound_set_subtitle_text_packet.rs | 8 - .../packets/game/clientbound_set_time_packet.rs | 9 - .../game/clientbound_set_title_text_packet.rs | 8 - .../clientbound_set_titles_animation_packet.rs | 9 - .../game/clientbound_sound_entity_packet.rs | 27 - .../src/packets/game/clientbound_sound_packet.rs | 29 - .../game/clientbound_start_configuration_packet.rs | 5 - .../packets/game/clientbound_stop_sound_packet.rs | 51 - .../game/clientbound_store_cookie_packet.rs | 9 - .../packets/game/clientbound_system_chat_packet.rs | 45 - .../packets/game/clientbound_tab_list_packet.rs | 28 - .../packets/game/clientbound_tag_query_packet.rs | 10 - .../game/clientbound_take_item_entity_packet.rs | 12 - .../game/clientbound_teleport_entity_packet.rs | 13 - .../game/clientbound_ticking_state_packet.rs | 8 - .../game/clientbound_ticking_step_packet.rs | 8 - .../packets/game/clientbound_transfer_packet.rs | 9 - .../game/clientbound_update_advancements_packet.rs | 205 -- .../game/clientbound_update_attributes_packet.rs | 18 - .../clientbound_update_enabled_features_packet.rs | 8 - .../game/clientbound_update_mob_effect_packet.rs | 15 - .../game/clientbound_update_recipes_packet.rs | 74 - .../packets/game/clientbound_update_tags_packet.rs | 74 - azalea-protocol/src/packets/game/mod.rs | 588 ++--- .../src/packets/game/s_accept_teleportation.rs | 8 + .../src/packets/game/s_block_entity_tag_query.rs | 10 + .../src/packets/game/s_bundle_item_selected.rs | 10 + .../src/packets/game/s_change_difficulty.rs | 8 + azalea-protocol/src/packets/game/s_chat.rs | 20 + azalea-protocol/src/packets/game/s_chat_ack.rs | 8 + azalea-protocol/src/packets/game/s_chat_command.rs | 7 + .../src/packets/game/s_chat_command_signed.rs | 20 + azalea-protocol/src/packets/game/s_chat_preview.rs | 8 + .../src/packets/game/s_chat_session_update.rs | 21 + .../src/packets/game/s_chunk_batch_received.rs | 7 + .../src/packets/game/s_client_command.rs | 13 + .../src/packets/game/s_client_information.rs | 9 + .../src/packets/game/s_client_tick_end.rs | 5 + .../src/packets/game/s_command_suggestion.rs | 9 + .../packets/game/s_configuration_acknowledged.rs | 5 + .../src/packets/game/s_container_button_click.rs | 8 + .../src/packets/game/s_container_click.rs | 17 + .../src/packets/game/s_container_close.rs | 7 + .../packets/game/s_container_slot_state_changed.rs | 11 + .../src/packets/game/s_cookie_response.rs | 9 + .../src/packets/game/s_custom_payload.rs | 10 + .../packets/game/s_debug_sample_subscription.rs | 12 + azalea-protocol/src/packets/game/s_edit_book.rs | 10 + .../src/packets/game/s_entity_tag_query.rs | 10 + azalea-protocol/src/packets/game/s_interact.rs | 86 + .../src/packets/game/s_jigsaw_generate.rs | 11 + azalea-protocol/src/packets/game/s_keep_alive.rs | 7 + .../src/packets/game/s_lock_difficulty.rs | 7 + .../src/packets/game/s_move_player_pos.rs | 10 + .../src/packets/game/s_move_player_pos_rot.rs | 12 + .../src/packets/game/s_move_player_rot.rs | 9 + .../src/packets/game/s_move_player_status_only.rs | 7 + azalea-protocol/src/packets/game/s_move_vehicle.rs | 11 + azalea-protocol/src/packets/game/s_paddle_boat.rs | 8 + azalea-protocol/src/packets/game/s_pick_item.rs | 8 + .../src/packets/game/s_pick_item_from_entity.rs | 9 + azalea-protocol/src/packets/game/s_ping_request.rs | 7 + azalea-protocol/src/packets/game/s_place_recipe.rs | 10 + .../src/packets/game/s_player_abilities.rs | 31 + .../src/packets/game/s_player_action.rs | 24 + .../src/packets/game/s_player_command.rs | 24 + azalea-protocol/src/packets/game/s_player_input.rs | 60 + .../src/packets/game/s_player_loaded.rs | 5 + azalea-protocol/src/packets/game/s_pong.rs | 7 + .../packets/game/s_recipe_book_change_settings.rs | 17 + .../src/packets/game/s_recipe_book_seen_recipe.rs | 8 + azalea-protocol/src/packets/game/s_rename_item.rs | 7 + .../src/packets/game/s_resource_pack.rs | 20 + .../src/packets/game/s_seen_advancements.rs | 41 + azalea-protocol/src/packets/game/s_select_trade.rs | 8 + azalea-protocol/src/packets/game/s_set_beacon.rs | 10 + .../src/packets/game/s_set_carried_item.rs | 7 + .../src/packets/game/s_set_command_block.rs | 63 + .../src/packets/game/s_set_command_minecart.rs | 10 + .../src/packets/game/s_set_creative_mode_slot.rs | 9 + .../src/packets/game/s_set_jigsaw_block.rs | 51 + .../src/packets/game/s_set_structure_block.rs | 98 + azalea-protocol/src/packets/game/s_sign_update.rs | 10 + azalea-protocol/src/packets/game/s_swing.rs | 9 + .../src/packets/game/s_teleport_to_entity.rs | 8 + azalea-protocol/src/packets/game/s_use_item.rs | 13 + azalea-protocol/src/packets/game/s_use_item_on.rs | 74 + .../serverbound_accept_teleportation_packet.rs | 8 - .../game/serverbound_block_entity_tag_query.rs | 10 - .../serverbound_block_entity_tag_query_packet.rs | 10 - .../game/serverbound_change_difficulty_packet.rs | 8 - .../packets/game/serverbound_chat_ack_packet.rs | 8 - .../game/serverbound_chat_command_packet.rs | 7 - .../game/serverbound_chat_command_signed_packet.rs | 20 - .../src/packets/game/serverbound_chat_packet.rs | 20 - .../game/serverbound_chat_preview_packet.rs | 8 - .../game/serverbound_chat_session_update_packet.rs | 21 - .../serverbound_chunk_batch_received_packet.rs | 7 - .../game/serverbound_client_command_packet.rs | 13 - .../game/serverbound_client_information_packet.rs | 9 - .../game/serverbound_client_tick_end_packet.rs | 5 - .../game/serverbound_command_suggestion_packet.rs | 9 - ...erverbound_configuration_acknowledged_packet.rs | 5 - .../serverbound_container_button_click_packet.rs | 8 - .../game/serverbound_container_click_packet.rs | 17 - .../game/serverbound_container_close_packet.rs | 7 - ...verbound_container_slot_state_changed_packet.rs | 11 - .../game/serverbound_cookie_response_packet.rs | 9 - .../game/serverbound_custom_payload_packet.rs | 10 - .../game/serverbound_debug_sample_subscription.rs | 12 - .../packets/game/serverbound_edit_book_packet.rs | 10 - .../packets/game/serverbound_entity_tag_query.rs | 10 - .../game/serverbound_entity_tag_query_packet.rs | 10 - .../packets/game/serverbound_interact_packet.rs | 86 - .../game/serverbound_jigsaw_generate_packet.rs | 11 - .../packets/game/serverbound_keep_alive_packet.rs | 7 - .../game/serverbound_lock_difficulty_packet.rs | 7 - .../game/serverbound_move_player_pos_packet.rs | 10 - .../game/serverbound_move_player_pos_rot_packet.rs | 12 - .../game/serverbound_move_player_rot_packet.rs | 9 - .../serverbound_move_player_status_only_packet.rs | 7 - .../game/serverbound_move_vehicle_packet.rs | 11 - .../packets/game/serverbound_paddle_boat_packet.rs | 8 - .../packets/game/serverbound_pick_item_packet.rs | 8 - .../game/serverbound_ping_request_packet.rs | 7 - .../game/serverbound_place_recipe_packet.rs | 10 - .../game/serverbound_player_abilities_packet.rs | 31 - .../game/serverbound_player_action_packet.rs | 24 - .../game/serverbound_player_command_packet.rs | 24 - .../game/serverbound_player_input_packet.rs | 60 - .../src/packets/game/serverbound_pong_packet.rs | 7 - ...rverbound_recipe_book_change_settings_packet.rs | 17 - .../serverbound_recipe_book_seen_recipe_packet.rs | 8 - .../packets/game/serverbound_rename_item_packet.rs | 7 - .../game/serverbound_resource_pack_packet.rs | 20 - .../game/serverbound_seen_advancements_packet.rs | 41 - .../game/serverbound_select_bundle_item_packet.rs | 10 - .../game/serverbound_select_trade_packet.rs | 8 - .../packets/game/serverbound_set_beacon_packet.rs | 10 - .../game/serverbound_set_carried_item_packet.rs | 7 - .../game/serverbound_set_command_block_packet.rs | 63 - .../serverbound_set_command_minecart_packet.rs | 10 - .../serverbound_set_creative_mode_slot_packet.rs | 9 - .../game/serverbound_set_jigsaw_block_packet.rs | 51 - .../game/serverbound_set_structure_block_packet.rs | 98 - .../packets/game/serverbound_sign_update_packet.rs | 10 - .../src/packets/game/serverbound_swing_packet.rs | 9 - .../game/serverbound_teleport_to_entity_packet.rs | 8 - .../packets/game/serverbound_use_item_on_packet.rs | 74 - .../packets/game/serverbound_use_item_packet.rs | 13 - azalea-protocol/src/packets/handshake/mod.rs | 12 + .../src/packets/handshake/s_intention.rs | 15 + .../packets/handshaking/client_intention_packet.rs | 15 - azalea-protocol/src/packets/handshaking/mod.rs | 11 - .../src/packets/login/c_cookie_request.rs | 8 + .../src/packets/login/c_custom_query.rs | 13 + azalea-protocol/src/packets/login/c_hello.rs | 11 + .../src/packets/login/c_login_compression.rs | 10 + .../src/packets/login/c_login_disconnect.rs | 32 + .../src/packets/login/c_login_finished.rs | 8 + .../login/clientbound_cookie_request_packet.rs | 8 - .../login/clientbound_custom_query_packet.rs | 13 - .../src/packets/login/clientbound_hello_packet.rs | 12 - .../login/clientbound_login_compression_packet.rs | 10 - .../login/clientbound_login_disconnect_packet.rs | 34 - .../login/clientbound_login_finished_packet.rs | 8 - azalea-protocol/src/packets/login/mod.rs | 46 +- .../src/packets/login/s_cookie_response.rs | 9 + .../src/packets/login/s_custom_query.rs | 9 + .../src/packets/login/s_custom_query_answer.rs | 11 + azalea-protocol/src/packets/login/s_hello.rs | 31 + azalea-protocol/src/packets/login/s_key.rs | 8 + .../src/packets/login/s_login_acknowledged.rs | 5 + .../login/serverbound_cookie_response_packet.rs | 9 - .../serverbound_custom_query_answer_packet.rs | 11 - .../login/serverbound_custom_query_packet.rs | 9 - .../src/packets/login/serverbound_hello_packet.rs | 30 - .../src/packets/login/serverbound_key_packet.rs | 8 - .../login/serverbound_login_acknowledged_packet.rs | 5 - azalea-protocol/src/packets/mod.rs | 28 +- .../src/packets/status/c_pong_response.rs | 7 + .../src/packets/status/c_status_response.rs | 61 + .../status/clientbound_pong_response_packet.rs | 7 - .../status/clientbound_status_response_packet.rs | 61 - azalea-protocol/src/packets/status/mod.rs | 25 +- .../src/packets/status/s_ping_request.rs | 7 + .../src/packets/status/s_status_request.rs | 5 + .../status/serverbound_ping_request_packet.rs | 7 - .../status/serverbound_status_request_packet.rs | 5 - azalea-protocol/src/read.rs | 10 +- azalea-protocol/src/write.rs | 126 +- azalea-registry/Cargo.toml | 2 +- azalea-registry/azalea-registry-macros/Cargo.toml | 2 +- azalea-registry/azalea-registry-macros/src/lib.rs | 2 +- azalea-registry/src/extra.rs | 34 + azalea-registry/src/lib.rs | 66 +- azalea-world/Cargo.toml | 2 +- azalea-world/src/chunk_storage.rs | 26 +- azalea-world/src/palette.rs | 32 +- azalea/Cargo.toml | 2 +- azalea/examples/steal.rs | 4 +- azalea/src/accept_resource_packs.rs | 30 +- azalea/src/auto_tool.rs | 8 +- azalea/src/container.rs | 6 +- azalea/src/pathfinder/debug.rs | 2 +- azalea/src/pathfinder/goals.rs | 2 +- azalea/src/pathfinder/mod.rs | 2 +- azalea/src/pathfinder/moves/basic.rs | 12 +- azalea/src/pathfinder/moves/mod.rs | 2 +- codegen/README.md | 32 +- codegen/genblocks.py | 34 +- codegen/genitemcomponents.py | 4 +- codegen/genpackets.py | 18 + codegen/genregistries.py | 1 - codegen/lib/code/blocks.py | 108 +- codegen/lib/code/entity.py | 4 +- codegen/lib/code/packet.py | 241 +- codegen/lib/code/shapes.py | 24 +- codegen/lib/code/utils.py | 6 +- codegen/lib/code/version.py | 38 +- codegen/lib/extract.py | 26 +- codegen/migrate.py | 121 +- codegen/newpacket.py | 24 +- 614 files changed, 9536 insertions(+), 9637 deletions(-) create mode 100644 azalea-protocol/src/common/client_information.rs create mode 100644 azalea-protocol/src/common/mod.rs create mode 100644 azalea-protocol/src/common/server_links.rs create mode 100644 azalea-protocol/src/packets/config/c_cookie_request.rs create mode 100644 azalea-protocol/src/packets/config/c_custom_payload.rs create mode 100644 azalea-protocol/src/packets/config/c_custom_report_details.rs create mode 100644 azalea-protocol/src/packets/config/c_disconnect.rs create mode 100644 azalea-protocol/src/packets/config/c_finish_configuration.rs create mode 100644 azalea-protocol/src/packets/config/c_keep_alive.rs create mode 100644 azalea-protocol/src/packets/config/c_ping.rs create mode 100644 azalea-protocol/src/packets/config/c_registry_data.rs create mode 100644 azalea-protocol/src/packets/config/c_reset_chat.rs create mode 100644 azalea-protocol/src/packets/config/c_resource_pack.rs create mode 100644 azalea-protocol/src/packets/config/c_resource_pack_pop.rs create mode 100644 azalea-protocol/src/packets/config/c_resource_pack_push.rs create mode 100644 azalea-protocol/src/packets/config/c_select_known_packs.rs create mode 100644 azalea-protocol/src/packets/config/c_server_links.rs create mode 100644 azalea-protocol/src/packets/config/c_store_cookie.rs create mode 100644 azalea-protocol/src/packets/config/c_transfer.rs create mode 100644 azalea-protocol/src/packets/config/c_update_enabled_features.rs create mode 100644 azalea-protocol/src/packets/config/c_update_tags.rs create mode 100755 azalea-protocol/src/packets/config/mod.rs create mode 100644 azalea-protocol/src/packets/config/s_client_information.rs create mode 100644 azalea-protocol/src/packets/config/s_cookie_response.rs create mode 100644 azalea-protocol/src/packets/config/s_custom_payload.rs create mode 100644 azalea-protocol/src/packets/config/s_finish_configuration.rs create mode 100644 azalea-protocol/src/packets/config/s_keep_alive.rs create mode 100644 azalea-protocol/src/packets/config/s_pong.rs create mode 100644 azalea-protocol/src/packets/config/s_resource_pack.rs create mode 100644 azalea-protocol/src/packets/config/s_select_known_packs.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_cookie_request_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_custom_payload_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_disconnect_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_finish_configuration_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_keep_alive_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_ping_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_registry_data_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_reset_chat_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_resource_pack_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_resource_pack_pop_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_resource_pack_push_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_select_known_packs_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_store_cookie_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_transfer_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_update_enabled_features_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/clientbound_update_tags_packet.rs delete mode 100755 azalea-protocol/src/packets/configuration/mod.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_client_information_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_cookie_response_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_custom_payload_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_finish_configuration_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_keep_alive_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_pong_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_resource_pack_packet.rs delete mode 100644 azalea-protocol/src/packets/configuration/serverbound_select_known_packs_packet.rs create mode 100755 azalea-protocol/src/packets/game/c_add_entity.rs create mode 100755 azalea-protocol/src/packets/game/c_add_experience_orb.rs create mode 100755 azalea-protocol/src/packets/game/c_add_player.rs create mode 100755 azalea-protocol/src/packets/game/c_animate.rs create mode 100755 azalea-protocol/src/packets/game/c_award_stats.rs create mode 100755 azalea-protocol/src/packets/game/c_block_changed_ack.rs create mode 100755 azalea-protocol/src/packets/game/c_block_destruction.rs create mode 100755 azalea-protocol/src/packets/game/c_block_entity_data.rs create mode 100755 azalea-protocol/src/packets/game/c_block_event.rs create mode 100755 azalea-protocol/src/packets/game/c_block_update.rs create mode 100755 azalea-protocol/src/packets/game/c_boss_event.rs create mode 100644 azalea-protocol/src/packets/game/c_bundle_delimiter.rs create mode 100755 azalea-protocol/src/packets/game/c_change_difficulty.rs create mode 100755 azalea-protocol/src/packets/game/c_chat_preview.rs create mode 100644 azalea-protocol/src/packets/game/c_chunk_batch_finished.rs create mode 100644 azalea-protocol/src/packets/game/c_chunk_batch_start.rs create mode 100644 azalea-protocol/src/packets/game/c_chunks_biomes.rs create mode 100644 azalea-protocol/src/packets/game/c_clear_titles.rs create mode 100755 azalea-protocol/src/packets/game/c_command_suggestions.rs create mode 100755 azalea-protocol/src/packets/game/c_commands.rs create mode 100644 azalea-protocol/src/packets/game/c_container_close.rs create mode 100755 azalea-protocol/src/packets/game/c_container_set_content.rs create mode 100755 azalea-protocol/src/packets/game/c_container_set_data.rs create mode 100755 azalea-protocol/src/packets/game/c_container_set_slot.rs create mode 100755 azalea-protocol/src/packets/game/c_cookie_request.rs create mode 100755 azalea-protocol/src/packets/game/c_cooldown.rs create mode 100755 azalea-protocol/src/packets/game/c_custom_chat_completions.rs create mode 100755 azalea-protocol/src/packets/game/c_custom_payload.rs create mode 100644 azalea-protocol/src/packets/game/c_custom_report_details.rs create mode 100644 azalea-protocol/src/packets/game/c_custom_sound.rs create mode 100644 azalea-protocol/src/packets/game/c_damage_event.rs create mode 100755 azalea-protocol/src/packets/game/c_debug_sample.rs create mode 100755 azalea-protocol/src/packets/game/c_delete_chat.rs create mode 100755 azalea-protocol/src/packets/game/c_disconnect.rs create mode 100644 azalea-protocol/src/packets/game/c_disguised_chat.rs create mode 100755 azalea-protocol/src/packets/game/c_entity_event.rs create mode 100755 azalea-protocol/src/packets/game/c_entity_position_sync.rs create mode 100755 azalea-protocol/src/packets/game/c_explode.rs create mode 100755 azalea-protocol/src/packets/game/c_forget_level_chunk.rs create mode 100755 azalea-protocol/src/packets/game/c_game_event.rs create mode 100755 azalea-protocol/src/packets/game/c_horse_screen_open.rs create mode 100644 azalea-protocol/src/packets/game/c_hurt_animation.rs create mode 100755 azalea-protocol/src/packets/game/c_initialize_border.rs create mode 100755 azalea-protocol/src/packets/game/c_keep_alive.rs create mode 100755 azalea-protocol/src/packets/game/c_level_chunk_with_light.rs create mode 100755 azalea-protocol/src/packets/game/c_level_event.rs create mode 100755 azalea-protocol/src/packets/game/c_level_particles.rs create mode 100755 azalea-protocol/src/packets/game/c_light_update.rs create mode 100755 azalea-protocol/src/packets/game/c_login.rs create mode 100755 azalea-protocol/src/packets/game/c_map_item_data.rs create mode 100755 azalea-protocol/src/packets/game/c_merchant_offers.rs create mode 100755 azalea-protocol/src/packets/game/c_move_entity_pos.rs create mode 100755 azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs create mode 100755 azalea-protocol/src/packets/game/c_move_entity_rot.rs create mode 100644 azalea-protocol/src/packets/game/c_move_minecart_along_track.rs create mode 100755 azalea-protocol/src/packets/game/c_move_vehicle.rs create mode 100755 azalea-protocol/src/packets/game/c_open_book.rs create mode 100755 azalea-protocol/src/packets/game/c_open_screen.rs create mode 100755 azalea-protocol/src/packets/game/c_open_sign_editor.rs create mode 100755 azalea-protocol/src/packets/game/c_ping.rs create mode 100755 azalea-protocol/src/packets/game/c_place_ghost_recipe.rs create mode 100755 azalea-protocol/src/packets/game/c_player_abilities.rs create mode 100644 azalea-protocol/src/packets/game/c_player_chat.rs create mode 100755 azalea-protocol/src/packets/game/c_player_chat_header.rs create mode 100755 azalea-protocol/src/packets/game/c_player_combat_end.rs create mode 100755 azalea-protocol/src/packets/game/c_player_combat_enter.rs create mode 100755 azalea-protocol/src/packets/game/c_player_combat_kill.rs create mode 100644 azalea-protocol/src/packets/game/c_player_info_remove.rs create mode 100644 azalea-protocol/src/packets/game/c_player_info_update.rs create mode 100755 azalea-protocol/src/packets/game/c_player_look_at.rs create mode 100755 azalea-protocol/src/packets/game/c_player_position.rs create mode 100755 azalea-protocol/src/packets/game/c_player_rotation.rs create mode 100755 azalea-protocol/src/packets/game/c_pong_response.rs create mode 100644 azalea-protocol/src/packets/game/c_projectile_power.rs create mode 100755 azalea-protocol/src/packets/game/c_recipe_book_add.rs create mode 100755 azalea-protocol/src/packets/game/c_recipe_book_remove.rs create mode 100755 azalea-protocol/src/packets/game/c_recipe_book_settings.rs create mode 100755 azalea-protocol/src/packets/game/c_remove_entities.rs create mode 100755 azalea-protocol/src/packets/game/c_remove_mob_effect.rs create mode 100644 azalea-protocol/src/packets/game/c_reset_score.rs create mode 100644 azalea-protocol/src/packets/game/c_resource_pack_pop.rs create mode 100644 azalea-protocol/src/packets/game/c_resource_pack_push.rs create mode 100755 azalea-protocol/src/packets/game/c_respawn.rs create mode 100755 azalea-protocol/src/packets/game/c_rotate_head.rs create mode 100755 azalea-protocol/src/packets/game/c_section_blocks_update.rs create mode 100755 azalea-protocol/src/packets/game/c_select_advancements_tab.rs create mode 100755 azalea-protocol/src/packets/game/c_server_data.rs create mode 100644 azalea-protocol/src/packets/game/c_server_links.rs create mode 100755 azalea-protocol/src/packets/game/c_set_action_bar_text.rs create mode 100755 azalea-protocol/src/packets/game/c_set_border_center.rs create mode 100755 azalea-protocol/src/packets/game/c_set_border_lerp_size.rs create mode 100755 azalea-protocol/src/packets/game/c_set_border_size.rs create mode 100755 azalea-protocol/src/packets/game/c_set_border_warning_delay.rs create mode 100755 azalea-protocol/src/packets/game/c_set_border_warning_distance.rs create mode 100755 azalea-protocol/src/packets/game/c_set_camera.rs create mode 100755 azalea-protocol/src/packets/game/c_set_chunk_cache_center.rs create mode 100755 azalea-protocol/src/packets/game/c_set_chunk_cache_radius.rs create mode 100644 azalea-protocol/src/packets/game/c_set_cursor_item.rs create mode 100755 azalea-protocol/src/packets/game/c_set_default_spawn_position.rs create mode 100755 azalea-protocol/src/packets/game/c_set_display_chat_preview.rs create mode 100755 azalea-protocol/src/packets/game/c_set_display_objective.rs create mode 100755 azalea-protocol/src/packets/game/c_set_entity_data.rs create mode 100755 azalea-protocol/src/packets/game/c_set_entity_link.rs create mode 100755 azalea-protocol/src/packets/game/c_set_entity_motion.rs create mode 100755 azalea-protocol/src/packets/game/c_set_equipment.rs create mode 100755 azalea-protocol/src/packets/game/c_set_experience.rs create mode 100755 azalea-protocol/src/packets/game/c_set_health.rs create mode 100644 azalea-protocol/src/packets/game/c_set_held_slot.rs create mode 100755 azalea-protocol/src/packets/game/c_set_objective.rs create mode 100755 azalea-protocol/src/packets/game/c_set_passengers.rs create mode 100644 azalea-protocol/src/packets/game/c_set_player_inventory.rs create mode 100755 azalea-protocol/src/packets/game/c_set_player_team.rs create mode 100755 azalea-protocol/src/packets/game/c_set_score.rs create mode 100755 azalea-protocol/src/packets/game/c_set_simulation_distance.rs create mode 100755 azalea-protocol/src/packets/game/c_set_subtitle_text.rs create mode 100755 azalea-protocol/src/packets/game/c_set_time.rs create mode 100755 azalea-protocol/src/packets/game/c_set_title_text.rs create mode 100755 azalea-protocol/src/packets/game/c_set_titles_animation.rs create mode 100755 azalea-protocol/src/packets/game/c_sound.rs create mode 100755 azalea-protocol/src/packets/game/c_sound_entity.rs create mode 100644 azalea-protocol/src/packets/game/c_start_configuration.rs create mode 100755 azalea-protocol/src/packets/game/c_stop_sound.rs create mode 100644 azalea-protocol/src/packets/game/c_store_cookie.rs create mode 100755 azalea-protocol/src/packets/game/c_system_chat.rs create mode 100755 azalea-protocol/src/packets/game/c_tab_list.rs create mode 100755 azalea-protocol/src/packets/game/c_tag_query.rs create mode 100755 azalea-protocol/src/packets/game/c_take_item_entity.rs create mode 100755 azalea-protocol/src/packets/game/c_teleport_entity.rs create mode 100644 azalea-protocol/src/packets/game/c_ticking_state.rs create mode 100644 azalea-protocol/src/packets/game/c_ticking_step.rs create mode 100644 azalea-protocol/src/packets/game/c_transfer.rs create mode 100755 azalea-protocol/src/packets/game/c_update_advancements.rs create mode 100755 azalea-protocol/src/packets/game/c_update_attributes.rs create mode 100644 azalea-protocol/src/packets/game/c_update_enabled_features.rs create mode 100755 azalea-protocol/src/packets/game/c_update_mob_effect.rs create mode 100755 azalea-protocol/src/packets/game/c_update_recipes.rs create mode 100755 azalea-protocol/src/packets/game/c_update_tags.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_add_experience_orb_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_add_player_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_animate_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_award_stats_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_block_changed_ack_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_block_destruction_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_block_entity_data_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_block_event_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_block_update_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_boss_event_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_bundle_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_chat_preview_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_chunk_batch_finished_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_chunk_batch_start_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_chunks_biomes_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_clear_titles_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_command_suggestions_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_commands_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_container_close_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_container_set_data_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_container_set_slot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_cookie_request_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_cooldown_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_custom_report_details_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_custom_sound_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_damage_event_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_debug_sample_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_entity_position_sync_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_explode_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_forget_level_chunk_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_game_event_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_horse_screen_open_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_hurt_animation_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_level_event_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_light_update_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_login_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_map_item_data_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_merchant_offers_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_move_entity_pos_rot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_move_minecart_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_move_vehicle_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_open_book_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_open_screen_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_open_sign_editor_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_ping_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_place_ghost_recipe_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_combat_end_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_combat_enter_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_combat_kill_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_player_info_remove_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_player_info_update_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_look_at_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_position_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_player_rotation_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_pong_response_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_projectile_power_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_recipe_book_add_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_recipe_book_remove_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_recipe_book_settings_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_remove_mob_effect_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_reset_score_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_resource_pack_pop_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_resource_pack_push_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_respawn_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_select_advancements_tab_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_server_data_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_server_links_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_action_bar_text_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_border_center_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_border_lerp_size_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_border_size_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_border_warning_delay_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_border_warning_distance_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_camera_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_chunk_cache_radius_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_set_cursor_item_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_display_chat_preview_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_display_objective_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_entity_motion_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_health_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_set_held_slot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_objective_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_passengers_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_set_player_inventory_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_player_team_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_score_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_simulation_distance_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_subtitle_text_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_time_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_title_text_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_set_titles_animation_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_sound_entity_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_sound_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_start_configuration_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_stop_sound_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_store_cookie_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_tab_list_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_tag_query_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_take_item_entity_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_ticking_state_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_ticking_step_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_transfer_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs delete mode 100644 azalea-protocol/src/packets/game/clientbound_update_enabled_features_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_update_mob_effect_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs delete mode 100755 azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs create mode 100755 azalea-protocol/src/packets/game/s_accept_teleportation.rs create mode 100644 azalea-protocol/src/packets/game/s_block_entity_tag_query.rs create mode 100644 azalea-protocol/src/packets/game/s_bundle_item_selected.rs create mode 100755 azalea-protocol/src/packets/game/s_change_difficulty.rs create mode 100755 azalea-protocol/src/packets/game/s_chat.rs create mode 100755 azalea-protocol/src/packets/game/s_chat_ack.rs create mode 100755 azalea-protocol/src/packets/game/s_chat_command.rs create mode 100755 azalea-protocol/src/packets/game/s_chat_command_signed.rs create mode 100755 azalea-protocol/src/packets/game/s_chat_preview.rs create mode 100644 azalea-protocol/src/packets/game/s_chat_session_update.rs create mode 100644 azalea-protocol/src/packets/game/s_chunk_batch_received.rs create mode 100755 azalea-protocol/src/packets/game/s_client_command.rs create mode 100755 azalea-protocol/src/packets/game/s_client_information.rs create mode 100644 azalea-protocol/src/packets/game/s_client_tick_end.rs create mode 100755 azalea-protocol/src/packets/game/s_command_suggestion.rs create mode 100644 azalea-protocol/src/packets/game/s_configuration_acknowledged.rs create mode 100755 azalea-protocol/src/packets/game/s_container_button_click.rs create mode 100755 azalea-protocol/src/packets/game/s_container_click.rs create mode 100755 azalea-protocol/src/packets/game/s_container_close.rs create mode 100644 azalea-protocol/src/packets/game/s_container_slot_state_changed.rs create mode 100644 azalea-protocol/src/packets/game/s_cookie_response.rs create mode 100755 azalea-protocol/src/packets/game/s_custom_payload.rs create mode 100644 azalea-protocol/src/packets/game/s_debug_sample_subscription.rs create mode 100755 azalea-protocol/src/packets/game/s_edit_book.rs create mode 100644 azalea-protocol/src/packets/game/s_entity_tag_query.rs create mode 100755 azalea-protocol/src/packets/game/s_interact.rs create mode 100755 azalea-protocol/src/packets/game/s_jigsaw_generate.rs create mode 100755 azalea-protocol/src/packets/game/s_keep_alive.rs create mode 100755 azalea-protocol/src/packets/game/s_lock_difficulty.rs create mode 100755 azalea-protocol/src/packets/game/s_move_player_pos.rs create mode 100755 azalea-protocol/src/packets/game/s_move_player_pos_rot.rs create mode 100755 azalea-protocol/src/packets/game/s_move_player_rot.rs create mode 100755 azalea-protocol/src/packets/game/s_move_player_status_only.rs create mode 100755 azalea-protocol/src/packets/game/s_move_vehicle.rs create mode 100755 azalea-protocol/src/packets/game/s_paddle_boat.rs create mode 100755 azalea-protocol/src/packets/game/s_pick_item.rs create mode 100644 azalea-protocol/src/packets/game/s_pick_item_from_entity.rs create mode 100755 azalea-protocol/src/packets/game/s_ping_request.rs create mode 100755 azalea-protocol/src/packets/game/s_place_recipe.rs create mode 100755 azalea-protocol/src/packets/game/s_player_abilities.rs create mode 100755 azalea-protocol/src/packets/game/s_player_action.rs create mode 100755 azalea-protocol/src/packets/game/s_player_command.rs create mode 100755 azalea-protocol/src/packets/game/s_player_input.rs create mode 100644 azalea-protocol/src/packets/game/s_player_loaded.rs create mode 100755 azalea-protocol/src/packets/game/s_pong.rs create mode 100755 azalea-protocol/src/packets/game/s_recipe_book_change_settings.rs create mode 100755 azalea-protocol/src/packets/game/s_recipe_book_seen_recipe.rs create mode 100755 azalea-protocol/src/packets/game/s_rename_item.rs create mode 100755 azalea-protocol/src/packets/game/s_resource_pack.rs create mode 100755 azalea-protocol/src/packets/game/s_seen_advancements.rs create mode 100755 azalea-protocol/src/packets/game/s_select_trade.rs create mode 100755 azalea-protocol/src/packets/game/s_set_beacon.rs create mode 100755 azalea-protocol/src/packets/game/s_set_carried_item.rs create mode 100755 azalea-protocol/src/packets/game/s_set_command_block.rs create mode 100755 azalea-protocol/src/packets/game/s_set_command_minecart.rs create mode 100755 azalea-protocol/src/packets/game/s_set_creative_mode_slot.rs create mode 100755 azalea-protocol/src/packets/game/s_set_jigsaw_block.rs create mode 100755 azalea-protocol/src/packets/game/s_set_structure_block.rs create mode 100755 azalea-protocol/src/packets/game/s_sign_update.rs create mode 100755 azalea-protocol/src/packets/game/s_swing.rs create mode 100755 azalea-protocol/src/packets/game/s_teleport_to_entity.rs create mode 100755 azalea-protocol/src/packets/game/s_use_item.rs create mode 100755 azalea-protocol/src/packets/game/s_use_item_on.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_block_entity_tag_query.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_block_entity_tag_query_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_change_difficulty_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_chat_command_signed_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_chat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_chat_preview_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_chat_session_update_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_chunk_batch_received_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_client_command_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_client_information_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_client_tick_end_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_command_suggestion_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_configuration_acknowledged_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_container_button_click_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_container_click_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_container_close_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_container_slot_state_changed_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_cookie_response_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_debug_sample_subscription.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_edit_book_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_entity_tag_query.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_entity_tag_query_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_interact_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_jigsaw_generate_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_lock_difficulty_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_move_player_pos_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_move_player_pos_rot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_move_player_rot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_move_player_status_only_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_move_vehicle_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_paddle_boat_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_pick_item_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_ping_request_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_place_recipe_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_player_abilities_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_player_action_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_player_command_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_player_input_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_pong_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_recipe_book_change_settings_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_recipe_book_seen_recipe_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_rename_item_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_resource_pack_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_seen_advancements_packet.rs delete mode 100644 azalea-protocol/src/packets/game/serverbound_select_bundle_item_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_select_trade_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_beacon_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_carried_item_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_command_block_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_command_minecart_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_creative_mode_slot_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_jigsaw_block_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_set_structure_block_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_sign_update_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_swing_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_teleport_to_entity_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_use_item_on_packet.rs delete mode 100755 azalea-protocol/src/packets/game/serverbound_use_item_packet.rs create mode 100755 azalea-protocol/src/packets/handshake/mod.rs create mode 100755 azalea-protocol/src/packets/handshake/s_intention.rs delete mode 100755 azalea-protocol/src/packets/handshaking/client_intention_packet.rs delete mode 100755 azalea-protocol/src/packets/handshaking/mod.rs create mode 100755 azalea-protocol/src/packets/login/c_cookie_request.rs create mode 100755 azalea-protocol/src/packets/login/c_custom_query.rs create mode 100755 azalea-protocol/src/packets/login/c_hello.rs create mode 100755 azalea-protocol/src/packets/login/c_login_compression.rs create mode 100755 azalea-protocol/src/packets/login/c_login_disconnect.rs create mode 100755 azalea-protocol/src/packets/login/c_login_finished.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_cookie_request_packet.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_hello_packet.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs delete mode 100755 azalea-protocol/src/packets/login/clientbound_login_finished_packet.rs create mode 100755 azalea-protocol/src/packets/login/s_cookie_response.rs create mode 100755 azalea-protocol/src/packets/login/s_custom_query.rs create mode 100644 azalea-protocol/src/packets/login/s_custom_query_answer.rs create mode 100755 azalea-protocol/src/packets/login/s_hello.rs create mode 100755 azalea-protocol/src/packets/login/s_key.rs create mode 100644 azalea-protocol/src/packets/login/s_login_acknowledged.rs delete mode 100755 azalea-protocol/src/packets/login/serverbound_cookie_response_packet.rs delete mode 100644 azalea-protocol/src/packets/login/serverbound_custom_query_answer_packet.rs delete mode 100755 azalea-protocol/src/packets/login/serverbound_custom_query_packet.rs delete mode 100755 azalea-protocol/src/packets/login/serverbound_hello_packet.rs delete mode 100755 azalea-protocol/src/packets/login/serverbound_key_packet.rs delete mode 100644 azalea-protocol/src/packets/login/serverbound_login_acknowledged_packet.rs create mode 100755 azalea-protocol/src/packets/status/c_pong_response.rs create mode 100755 azalea-protocol/src/packets/status/c_status_response.rs delete mode 100755 azalea-protocol/src/packets/status/clientbound_pong_response_packet.rs delete mode 100755 azalea-protocol/src/packets/status/clientbound_status_response_packet.rs create mode 100755 azalea-protocol/src/packets/status/s_ping_request.rs create mode 100755 azalea-protocol/src/packets/status/s_status_request.rs delete mode 100755 azalea-protocol/src/packets/status/serverbound_ping_request_packet.rs delete mode 100755 azalea-protocol/src/packets/status/serverbound_status_request_packet.rs create mode 100755 codegen/genpackets.py diff --git a/Cargo.lock b/Cargo.lock index 7e285f21..f7243fd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,7 +190,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "azalea" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "anyhow", "azalea-auth", @@ -229,7 +229,7 @@ dependencies = [ [[package]] name = "azalea-auth" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-crypto", @@ -249,7 +249,7 @@ dependencies = [ [[package]] name = "azalea-block" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-block-macros", "azalea-buf", @@ -258,7 +258,7 @@ dependencies = [ [[package]] name = "azalea-block-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "proc-macro2", "quote", @@ -267,7 +267,7 @@ dependencies = [ [[package]] name = "azalea-brigadier" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-chat", @@ -278,7 +278,7 @@ dependencies = [ [[package]] name = "azalea-buf" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf-macros", "byteorder", @@ -291,7 +291,7 @@ dependencies = [ [[package]] name = "azalea-buf-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "proc-macro2", "quote", @@ -300,7 +300,7 @@ dependencies = [ [[package]] name = "azalea-chat" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-language", @@ -313,7 +313,7 @@ dependencies = [ [[package]] name = "azalea-client" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "anyhow", "azalea-auth", @@ -347,7 +347,7 @@ dependencies = [ [[package]] name = "azalea-core" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-registry", @@ -361,7 +361,7 @@ dependencies = [ [[package]] name = "azalea-crypto" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "aes", "azalea-buf", @@ -378,7 +378,7 @@ dependencies = [ [[package]] name = "azalea-entity" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-block", "azalea-buf", @@ -401,7 +401,7 @@ dependencies = [ [[package]] name = "azalea-inventory" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-chat", @@ -414,7 +414,7 @@ dependencies = [ [[package]] name = "azalea-inventory-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "proc-macro2", "quote", @@ -423,7 +423,7 @@ dependencies = [ [[package]] name = "azalea-language" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "serde", "serde_json", @@ -431,7 +431,7 @@ dependencies = [ [[package]] name = "azalea-physics" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-block", "azalea-core", @@ -447,7 +447,7 @@ dependencies = [ [[package]] name = "azalea-protocol" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "anyhow", "async-recursion", @@ -484,7 +484,7 @@ dependencies = [ [[package]] name = "azalea-protocol-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "proc-macro2", "quote", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "azalea-registry" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-buf", "azalea-registry-macros", @@ -503,7 +503,7 @@ dependencies = [ [[package]] name = "azalea-registry-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "quote", "syn", @@ -511,7 +511,7 @@ dependencies = [ [[package]] name = "azalea-world" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" dependencies = [ "azalea-block", "azalea-buf", @@ -1381,9 +1381,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1661,7 +1661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -1707,9 +1707,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" @@ -1731,9 +1731,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.164" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libm" @@ -2346,9 +2346,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest", @@ -2405,9 +2405,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "once_cell", "ring", @@ -2911,9 +2911,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2922,9 +2922,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -2933,9 +2933,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", diff --git a/README.md b/README.md index bdfebeb2..a8d40905 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ A collection of Rust crates for making Minecraft bots, clients, and tools. -_Currently supported Minecraft version: `1.21.2`._ +_Currently supported Minecraft version: `1.21.3`._ > [!WARNING] > Azalea is still very unfinished, though most crates are in a somewhat useable state diff --git a/azalea-auth/Cargo.toml b/azalea-auth/Cargo.toml index 6573081d..ec39650c 100644 --- a/azalea-auth/Cargo.toml +++ b/azalea-auth/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-auth" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-auth" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-auth/src/game_profile.rs b/azalea-auth/src/game_profile.rs index 31650754..af00712d 100755 --- a/azalea-auth/src/game_profile.rs +++ b/azalea-auth/src/game_profile.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use serde::{Deserialize, Serialize}; use uuid::Uuid; -#[derive(McBuf, Debug, Clone, Default, Eq, PartialEq)] +#[derive(AzBuf, Debug, Clone, Default, Eq, PartialEq)] pub struct GameProfile { /// The UUID of the player. pub uuid: Uuid, @@ -43,7 +43,7 @@ impl From for GameProfile { } } -#[derive(McBuf, Debug, Clone, Eq, PartialEq)] +#[derive(AzBuf, Debug, Clone, Eq, PartialEq)] pub struct ProfilePropertyValue { pub value: String, pub signature: Option, diff --git a/azalea-block/Cargo.toml b/azalea-block/Cargo.toml index dc0bc199..87e3a726 100644 --- a/azalea-block/Cargo.toml +++ b/azalea-block/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-block" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-block" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [lib] diff --git a/azalea-block/README.md b/azalea-block/README.md index 9be4c79b..ae3b8c5f 100755 --- a/azalea-block/README.md +++ b/azalea-block/README.md @@ -9,10 +9,10 @@ There's three block types, used for different things. You can (mostly) convert b ``` # use azalea_block::BlockState; let block_state: BlockState = azalea_block::blocks::CobblestoneWall { - east: azalea_block::properties::EastWall::Low, - north: azalea_block::properties::NorthWall::Low, - south: azalea_block::properties::SouthWall::Low, - west: azalea_block::properties::WestWall::Low, + east: azalea_block::properties::WallEast::Low, + north: azalea_block::properties::WallNorth::Low, + south: azalea_block::properties::WallSouth::Low, + west: azalea_block::properties::WallWest::Low, up: false, waterlogged: false, } diff --git a/azalea-block/azalea-block-macros/Cargo.toml b/azalea-block/azalea-block-macros/Cargo.toml index 8e3885c1..70adb167 100644 --- a/azalea-block/azalea-block-macros/Cargo.toml +++ b/azalea-block/azalea-block-macros/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-block-macros" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-block/azalea-block-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [lib] proc-macro = true diff --git a/azalea-block/src/generated.rs b/azalea-block/src/generated.rs index 18ee93fc..00f1299f 100755 --- a/azalea-block/src/generated.rs +++ b/azalea-block/src/generated.rs @@ -7,6 +7,11 @@ use crate::{Block, BlockBehavior, BlockState, BlockStates, Property}; make_block_states! { Properties => { "snowy" => Snowy(bool), + "axis" => Axis { + X, + Y, + Z, + }, "stage" => OakSaplingStage { _0, _1, @@ -35,6 +40,10 @@ make_block_states! { _0, _1, }, + "stage" => PaleOakSaplingStage { + _0, + _1, + }, "age" => MangrovePropaguleAge { _0, _1, @@ -96,11 +105,6 @@ make_block_states! { _2, _3, }, - "axis" => Axis { - X, - Y, - Z, - }, "distance" => OakLeavesDistance { _1, _2, @@ -165,6 +169,15 @@ make_block_states! { _6, _7, }, + "distance" => PaleOakLeavesDistance { + _1, + _2, + _3, + _4, + _5, + _6, + _7, + }, "distance" => MangroveLeavesDistance { _1, _2, @@ -284,7 +297,12 @@ make_block_states! { }, "short" => Short(bool), "unstable" => Unstable(bool), - "slot_5_occupied" => TrueFalse(bool), + "slot_0_occupied" => Slot0Occupied(bool), + "slot_1_occupied" => Slot1Occupied(bool), + "slot_2_occupied" => Slot2Occupied(bool), + "slot_3_occupied" => Slot3Occupied(bool), + "slot_4_occupied" => Slot4Occupied(bool), + "slot_5_occupied" => Slot5Occupied(bool), "age" => FireAge { _0, _1, @@ -308,6 +326,11 @@ make_block_states! { "south" => South(bool), "up" => Up(bool), "west" => West(bool), + "creaking" => Creaking { + Disabled, + Dormant, + Active, + }, "half" => TopBottom { Top, Bottom, @@ -509,6 +532,24 @@ make_block_states! { _14, _15, }, + "rotation" => PaleOakSignRotation { + _0, + _1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, + _9, + _10, + _11, + _12, + _13, + _14, + _15, + }, "rotation" => MangroveSignRotation { _0, _1, @@ -689,6 +730,24 @@ make_block_states! { _14, _15, }, + "rotation" => PaleOakHangingSignRotation { + _0, + _1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, + _9, + _10, + _11, + _12, + _13, + _14, + _15, + }, "rotation" => CrimsonHangingSignRotation { _0, _1, @@ -882,22 +941,22 @@ make_block_states! { }, "disarmed" => Disarmed(bool), "conditional" => Conditional(bool), - "east" => EastWall { + "east" => WallEast { None, Low, Tall, }, - "north" => NorthWall { + "north" => WallNorth { None, Low, Tall, }, - "south" => SouthWall { + "south" => WallSouth { None, Low, Tall, }, - "west" => WestWall { + "west" => WallWest { None, Low, Tall, @@ -1438,17 +1497,13 @@ make_block_states! { _0, _1, }, - "age" => _0_1_2_3_4 { + "age" => PitcherCropAge { _0, _1, _2, _3, _4, }, - "half" => UpperLower { - Upper, - Lower, - }, "age" => BeetrootsAge { _0, _1, @@ -1673,7 +1728,7 @@ make_block_states! { _7, _8, }, - "power" => TargetOutputPower { + "power" => TargetPower { _0, _1, _2, @@ -1707,7 +1762,7 @@ make_block_states! { _4, _5, }, - "charges" => RespawnAnchorCharge { + "charges" => RespawnAnchorCharges { _0, _1, _2, @@ -1834,7 +1889,7 @@ make_block_states! { _14, _15, }, - "sculk_sensor_phase" => Phase { + "sculk_sensor_phase" => SculkSensorPhase { Inactive, Active, Cooldown, @@ -1867,7 +1922,7 @@ make_block_states! { Middle, Base, }, - "vertical_direction" => TipDirection { + "vertical_direction" => VerticalDirection { Up, Down, }, @@ -1900,7 +1955,7 @@ make_block_states! { _25, }, "berries" => Berries(bool), - "flower_amount" => PinkPetalsAmount { + "flower_amount" => PinkPetalsFlowerAmount { _1, _2, _3, @@ -1912,11 +1967,6 @@ make_block_states! { Partial, Full, }, - "axis" => Falling { - X, - Y, - Z, - }, "cracked" => Cracked(bool), "crafting" => Crafting(bool), "ominous" => Ominous(bool), @@ -1934,6 +1984,7 @@ make_block_states! { Unlocking, Ejecting, }, + "tip" => Tip(bool), }, Blocks => { air => BlockBehavior::new(), {}, @@ -1960,6 +2011,10 @@ make_block_states! { acacia_planks => BlockBehavior::new().strength(2.0, 3.0), {}, cherry_planks => BlockBehavior::new().strength(2.0, 3.0), {}, dark_oak_planks => BlockBehavior::new().strength(2.0, 3.0), {}, + pale_oak_wood => BlockBehavior::new(), { + "axis": Axis::Y, + }, + pale_oak_planks => BlockBehavior::new(), {}, mangrove_planks => BlockBehavior::new().strength(2.0, 3.0), {}, bamboo_planks => BlockBehavior::new().strength(2.0, 3.0), {}, bamboo_mosaic => BlockBehavior::new().strength(2.0, 3.0), {}, @@ -1984,6 +2039,9 @@ make_block_states! { dark_oak_sapling => BlockBehavior::new(), { "stage": DarkOakSaplingStage::_0, }, + pale_oak_sapling => BlockBehavior::new(), { + "stage": PaleOakSaplingStage::_0, + }, mangrove_propagule => BlockBehavior::new(), { "age": MangrovePropaguleAge::_0, "hanging": Hanging(false), @@ -2034,6 +2092,9 @@ make_block_states! { dark_oak_log => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, + pale_oak_log => BlockBehavior::new(), { + "axis": Axis::Y, + }, mangrove_log => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, @@ -2064,6 +2125,9 @@ make_block_states! { stripped_dark_oak_log => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, + stripped_pale_oak_log => BlockBehavior::new(), { + "axis": Axis::Y, + }, stripped_oak_log => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, @@ -2118,6 +2182,9 @@ make_block_states! { stripped_dark_oak_wood => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, + stripped_pale_oak_wood => BlockBehavior::new(), { + "axis": Axis::Y, + }, stripped_mangrove_wood => BlockBehavior::new().strength(2.0, 2.0), { "axis": Axis::Y, }, @@ -2156,6 +2223,11 @@ make_block_states! { "persistent": Persistent(false), "waterlogged": Waterlogged(false), }, + pale_oak_leaves => BlockBehavior::new(), { + "distance": PaleOakLeavesDistance::_7, + "persistent": Persistent(false), + "waterlogged": Waterlogged(false), + }, mangrove_leaves => BlockBehavior::new().strength(0.2, 0.2), { "distance": MangroveLeavesDistance::_7, "persistent": Persistent(false), @@ -2345,12 +2417,12 @@ make_block_states! { bookshelf => BlockBehavior::new().strength(1.5, 1.5), {}, chiseled_bookshelf => BlockBehavior::new().strength(1.5, 1.5), { "facing": FacingCardinal::North, - "slot_0_occupied": TrueFalse(false), - "slot_1_occupied": TrueFalse(false), - "slot_2_occupied": TrueFalse(false), - "slot_3_occupied": TrueFalse(false), - "slot_4_occupied": TrueFalse(false), - "slot_5_occupied": TrueFalse(false), + "slot_0_occupied": Slot0Occupied(false), + "slot_1_occupied": Slot1Occupied(false), + "slot_2_occupied": Slot2Occupied(false), + "slot_3_occupied": Slot3Occupied(false), + "slot_4_occupied": Slot4Occupied(false), + "slot_5_occupied": Slot5Occupied(false), }, mossy_cobblestone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {}, obsidian => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {}, @@ -2368,6 +2440,10 @@ make_block_states! { }, soul_fire => BlockBehavior::new(), {}, spawner => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {}, + creaking_heart => BlockBehavior::new(), { + "axis": Axis::Y, + "creaking": Creaking::Disabled, + }, oak_stairs => BlockBehavior::new().strength(2.0, 3.0), { "facing": FacingCardinal::North, "half": TopBottom::Bottom, @@ -2428,6 +2504,10 @@ make_block_states! { "rotation": DarkOakSignRotation::_0, "waterlogged": Waterlogged(false), }, + pale_oak_sign => BlockBehavior::new(), { + "rotation": PaleOakSignRotation::_0, + "waterlogged": Waterlogged(false), + }, mangrove_sign => BlockBehavior::new().strength(1.0, 1.0), { "rotation": MangroveSignRotation::_0, "waterlogged": Waterlogged(false), @@ -2485,6 +2565,10 @@ make_block_states! { "facing": FacingCardinal::North, "waterlogged": Waterlogged(false), }, + pale_oak_wall_sign => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "waterlogged": Waterlogged(false), + }, mangrove_wall_sign => BlockBehavior::new().strength(1.0, 1.0), { "facing": FacingCardinal::North, "waterlogged": Waterlogged(false), @@ -2528,6 +2612,11 @@ make_block_states! { "rotation": DarkOakHangingSignRotation::_0, "waterlogged": Waterlogged(false), }, + pale_oak_hanging_sign => BlockBehavior::new(), { + "attached": Attached(false), + "rotation": PaleOakHangingSignRotation::_0, + "waterlogged": Waterlogged(false), + }, crimson_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), { "attached": Attached(false), "rotation": CrimsonHangingSignRotation::_0, @@ -2576,6 +2665,10 @@ make_block_states! { "facing": FacingCardinal::North, "waterlogged": Waterlogged(false), }, + pale_oak_wall_hanging_sign => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "waterlogged": Waterlogged(false), + }, mangrove_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), { "facing": FacingCardinal::North, "waterlogged": Waterlogged(false), @@ -2628,6 +2721,9 @@ make_block_states! { dark_oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), { "powered": Powered(false), }, + pale_oak_pressure_plate => BlockBehavior::new(), { + "powered": Powered(false), + }, mangrove_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), { "powered": Powered(false), }, @@ -2771,6 +2867,13 @@ make_block_states! { "powered": Powered(false), "waterlogged": Waterlogged(false), }, + pale_oak_trapdoor => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "half": TopBottom::Bottom, + "open": Open(false), + "powered": Powered(false), + "waterlogged": Waterlogged(false), + }, mangrove_trapdoor => BlockBehavior::new().strength(3.0, 3.0), { "facing": FacingCardinal::North, "half": TopBottom::Bottom, @@ -2993,20 +3096,20 @@ make_block_states! { }, beacon => BlockBehavior::new().strength(3.0, 3.0), {}, cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, mossy_cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, flower_pot => BlockBehavior::new(), {}, potted_torchflower => BlockBehavior::new(), {}, @@ -3017,6 +3120,7 @@ make_block_states! { potted_acacia_sapling => BlockBehavior::new(), {}, potted_cherry_sapling => BlockBehavior::new(), {}, potted_dark_oak_sapling => BlockBehavior::new(), {}, + potted_pale_oak_sapling => BlockBehavior::new(), {}, potted_mangrove_propagule => BlockBehavior::new(), {}, potted_fern => BlockBehavior::new(), {}, potted_dandelion => BlockBehavior::new(), {}, @@ -3077,6 +3181,11 @@ make_block_states! { "facing": FacingCardinal::North, "powered": Powered(false), }, + pale_oak_button => BlockBehavior::new(), { + "face": Face::Wall, + "facing": FacingCardinal::North, + "powered": Powered(false), + }, mangrove_button => BlockBehavior::new().strength(0.5, 0.5), { "face": Face::Wall, "facing": FacingCardinal::North, @@ -3344,6 +3453,12 @@ make_block_states! { "shape": StairShape::Straight, "waterlogged": Waterlogged(false), }, + pale_oak_stairs => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "half": TopBottom::Bottom, + "shape": StairShape::Straight, + "waterlogged": Waterlogged(false), + }, mangrove_stairs => BlockBehavior::new().strength(2.0, 3.0), { "facing": FacingCardinal::North, "half": TopBottom::Bottom, @@ -3584,6 +3699,10 @@ make_block_states! { "type": Type::Bottom, "waterlogged": Waterlogged(false), }, + pale_oak_slab => BlockBehavior::new(), { + "type": Type::Bottom, + "waterlogged": Waterlogged(false), + }, mangrove_slab => BlockBehavior::new().strength(2.0, 3.0), { "type": Type::Bottom, "waterlogged": Waterlogged(false), @@ -3692,6 +3811,12 @@ make_block_states! { "open": Open(false), "powered": Powered(false), }, + pale_oak_fence_gate => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "in_wall": InWall(false), + "open": Open(false), + "powered": Powered(false), + }, mangrove_fence_gate => BlockBehavior::new().strength(2.0, 3.0), { "facing": FacingCardinal::North, "in_wall": InWall(false), @@ -3746,6 +3871,13 @@ make_block_states! { "waterlogged": Waterlogged(false), "west": West(false), }, + pale_oak_fence => BlockBehavior::new(), { + "east": East(false), + "north": North(false), + "south": South(false), + "waterlogged": Waterlogged(false), + "west": West(false), + }, mangrove_fence => BlockBehavior::new().strength(2.0, 3.0), { "east": East(false), "north": North(false), @@ -3802,6 +3934,13 @@ make_block_states! { "open": Open(false), "powered": Powered(false), }, + pale_oak_door => BlockBehavior::new(), { + "facing": FacingCardinal::North, + "half": Half::Lower, + "hinge": Hinge::Left, + "open": Open(false), + "powered": Powered(false), + }, mangrove_door => BlockBehavior::new().strength(3.0, 3.0), { "facing": FacingCardinal::North, "half": Half::Lower, @@ -3845,8 +3984,8 @@ make_block_states! { "age": TorchflowerCropAge::_0, }, pitcher_crop => BlockBehavior::new(), { - "age": _0_1_2_3_4::_0, - "half": UpperLower::Lower, + "age": PitcherCropAge::_0, + "half": Half::Lower, }, pitcher_plant => BlockBehavior::new(), { "half": Half::Lower, @@ -4288,108 +4427,108 @@ make_block_states! { "waterlogged": Waterlogged(false), }, brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, prismarine_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, red_sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, mossy_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, granite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, mud_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, andesite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, red_nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, end_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, diorite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, scaffolding => BlockBehavior::new(), { "bottom": Bottom(false), @@ -4613,7 +4752,7 @@ make_block_states! { "level": ComposterLevel::_0, }, target => BlockBehavior::new().strength(0.5, 0.5), { - "power": TargetOutputPower::_0, + "power": TargetPower::_0, }, bee_nest => BlockBehavior::new().strength(0.3, 0.3), { "facing": FacingCardinal::North, @@ -4629,7 +4768,7 @@ make_block_states! { ancient_debris => BlockBehavior::new().requires_correct_tool_for_drops().strength(30.0, 1200.0), {}, crying_obsidian => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {}, respawn_anchor => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), { - "charges": RespawnAnchorCharge::_0, + "charges": RespawnAnchorCharges::_0, }, potted_crimson_fungus => BlockBehavior::new(), {}, potted_warped_fungus => BlockBehavior::new(), {}, @@ -4644,12 +4783,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, blackstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { "type": Type::Bottom, @@ -4670,12 +4809,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, polished_blackstone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, gilded_blackstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {}, polished_blackstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { @@ -4697,12 +4836,12 @@ make_block_states! { "powered": Powered(false), }, polished_blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, chiseled_nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {}, cracked_nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {}, @@ -4873,12 +5012,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, polished_tuff => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {}, polished_tuff_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { @@ -4892,12 +5031,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, polished_tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, chiseled_tuff => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {}, tuff_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {}, @@ -4912,12 +5051,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, tuff_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, chiseled_tuff_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {}, calcite => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.75, 0.75), {}, @@ -4925,13 +5064,13 @@ make_block_states! { powder_snow => BlockBehavior::new().strength(0.25, 0.25), {}, sculk_sensor => BlockBehavior::new().strength(1.5, 1.5), { "power": SculkSensorPower::_0, - "sculk_sensor_phase": Phase::Inactive, + "sculk_sensor_phase": SculkSensorPhase::Inactive, "waterlogged": Waterlogged(false), }, calibrated_sculk_sensor => BlockBehavior::new().strength(1.5, 1.5), { "facing": FacingCardinal::North, "power": CalibratedSculkSensorPower::_0, - "sculk_sensor_phase": Phase::Inactive, + "sculk_sensor_phase": SculkSensorPhase::Inactive, "waterlogged": Waterlogged(false), }, sculk => BlockBehavior::new().strength(0.2, 0.2), {}, @@ -5233,7 +5372,7 @@ make_block_states! { }, pointed_dripstone => BlockBehavior::new().strength(1.5, 3.0), { "thickness": Thickness::Tip, - "vertical_direction": TipDirection::Up, + "vertical_direction": VerticalDirection::Up, "waterlogged": Waterlogged(false), }, dripstone_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.0), {}, @@ -5250,7 +5389,7 @@ make_block_states! { moss_carpet => BlockBehavior::new().strength(0.1, 0.1), {}, pink_petals => BlockBehavior::new(), { "facing": FacingCardinal::North, - "flower_amount": PinkPetalsAmount::_1, + "flower_amount": PinkPetalsFlowerAmount::_1, }, moss_block => BlockBehavior::new().strength(0.1, 0.1), {}, big_dripleaf => BlockBehavior::new().strength(0.1, 0.1), { @@ -5287,12 +5426,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, cobbled_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, polished_deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, polished_deepslate_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { @@ -5306,12 +5445,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, polished_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, deepslate_tiles => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, deepslate_tile_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { @@ -5325,12 +5464,12 @@ make_block_states! { "waterlogged": Waterlogged(false), }, deepslate_tile_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, deepslate_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, deepslate_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { @@ -5344,18 +5483,18 @@ make_block_states! { "waterlogged": Waterlogged(false), }, deepslate_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), { - "east": EastWall::None, - "north": NorthWall::None, - "south": SouthWall::None, + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, "up": Up(true), "waterlogged": Waterlogged(false), - "west": WestWall::None, + "west": WallWest::None, }, chiseled_deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, cracked_deepslate_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, cracked_deepslate_tiles => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {}, infested_deepslate => BlockBehavior::new().strength(1.5, 0.75), { - "axis": Falling::Y, + "axis": Axis::Y, }, smooth_basalt => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {}, raw_iron_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {}, @@ -5396,5 +5535,16 @@ make_block_states! { heavy_core => BlockBehavior::new(), { "waterlogged": Waterlogged(false), }, + pale_moss_block => BlockBehavior::new(), {}, + pale_moss_carpet => BlockBehavior::new(), { + "bottom": Bottom(true), + "east": WallEast::None, + "north": WallNorth::None, + "south": WallSouth::None, + "west": WallWest::None, + }, + pale_hanging_moss => BlockBehavior::new(), { + "tip": Tip(true), + }, } } diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index 7e6ccfaf..c1655919 100755 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -11,7 +11,7 @@ use std::{ io::{Cursor, Write}, }; -use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; pub use behavior::BlockBehavior; pub use generated::{blocks, properties}; pub use range::BlockStates; @@ -80,17 +80,17 @@ impl TryFrom for BlockState { } } -impl McBufReadable for BlockState { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let state_id = u32::var_read_from(buf)?; +impl AzaleaRead for BlockState { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let state_id = u32::azalea_read_var(buf)?; Self::try_from(state_id).map_err(|_| BufReadError::UnexpectedEnumVariant { id: state_id as i32, }) } } -impl McBufWritable for BlockState { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u32::var_write_into(&self.id, buf) +impl AzaleaWrite for BlockState { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u32::azalea_write_var(&self.id, buf) } } diff --git a/azalea-brigadier/Cargo.toml b/azalea-brigadier/Cargo.toml index 167559ea..2b5bddcc 100644 --- a/azalea-brigadier/Cargo.toml +++ b/azalea-brigadier/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-brigadier" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-brigadier" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-brigadier/src/suggestion/mod.rs b/azalea-brigadier/src/suggestion/mod.rs index 753b1bc8..a31b6837 100755 --- a/azalea-brigadier/src/suggestion/mod.rs +++ b/azalea-brigadier/src/suggestion/mod.rs @@ -9,7 +9,7 @@ use std::{ }; #[cfg(feature = "azalea-buf")] -use azalea_buf::McBufWritable; +use azalea_buf::AzaleaWrite; #[cfg(feature = "azalea-buf")] use azalea_chat::FormattedText; pub use suggestions::Suggestions; @@ -137,13 +137,13 @@ impl PartialOrd for SuggestionValue { } #[cfg(feature = "azalea-buf")] -impl McBufWritable for Suggestion { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.value.to_string().write_into(buf)?; +impl AzaleaWrite for Suggestion { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.value.to_string().azalea_write(buf)?; self.tooltip .clone() .map(FormattedText::from) - .write_into(buf)?; + .azalea_write(buf)?; Ok(()) } } diff --git a/azalea-brigadier/src/suggestion/suggestions.rs b/azalea-brigadier/src/suggestion/suggestions.rs index 5941aa7d..60eaa111 100755 --- a/azalea-brigadier/src/suggestion/suggestions.rs +++ b/azalea-brigadier/src/suggestion/suggestions.rs @@ -3,9 +3,7 @@ use std::io::{Cursor, Write}; use std::{collections::HashSet, hash::Hash}; #[cfg(feature = "azalea-buf")] -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; #[cfg(feature = "azalea-buf")] use azalea_chat::FormattedText; @@ -79,21 +77,21 @@ impl Suggestions { } #[cfg(feature = "azalea-buf")] -impl McBufReadable for Suggestions { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - #[derive(McBuf)] +impl AzaleaRead for Suggestions { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + #[derive(AzBuf)] struct StandaloneSuggestion { pub text: String, pub tooltip: Option, } - let start = u32::var_read_from(buf)? as usize; - let length = u32::var_read_from(buf)? as usize; + let start = u32::azalea_read_var(buf)? as usize; + let length = u32::azalea_read_var(buf)? as usize; let range = StringRange::between(start, start + length); // the range of a Suggestion depends on the Suggestions containing it, - // so we can't just `impl McBufReadable for Suggestion` - let mut suggestions = Vec::::read_from(buf)? + // so we can't just `impl AzaleaRead for Suggestion` + let mut suggestions = Vec::::azalea_read(buf)? .into_iter() .map(|s| Suggestion { value: SuggestionValue::Text(s.text), @@ -108,11 +106,11 @@ impl McBufReadable for Suggestions { } #[cfg(feature = "azalea-buf")] -impl McBufWritable for Suggestions { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (self.range.start() as u32).var_write_into(buf)?; - (self.range.length() as u32).var_write_into(buf)?; - self.suggestions.write_into(buf)?; +impl AzaleaWrite for Suggestions { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.range.start() as u32).azalea_write_var(buf)?; + (self.range.length() as u32).azalea_write_var(buf)?; + self.suggestions.azalea_write(buf)?; Ok(()) } } diff --git a/azalea-buf/Cargo.toml b/azalea-buf/Cargo.toml index c8b29c6f..3c8572c8 100644 --- a/azalea-buf/Cargo.toml +++ b/azalea-buf/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-buf" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-buf" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-buf/azalea-buf-macros/Cargo.toml b/azalea-buf/azalea-buf-macros/Cargo.toml index 85545a75..8920d035 100644 --- a/azalea-buf/azalea-buf-macros/Cargo.toml +++ b/azalea-buf/azalea-buf-macros/Cargo.toml @@ -1,10 +1,10 @@ [package] -description = "#[derive(McBuf)]" +description = "#[derive(AzBuf)]" edition = "2021" license = "MIT" name = "azalea-buf-macros" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-buf" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [lib] proc-macro = true diff --git a/azalea-buf/azalea-buf-macros/src/lib.rs b/azalea-buf/azalea-buf-macros/src/lib.rs index 4d17daa6..dec624e3 100755 --- a/azalea-buf/azalea-buf-macros/src/lib.rs +++ b/azalea-buf/azalea-buf-macros/src/lib.rs @@ -5,26 +5,26 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; -#[proc_macro_derive(McBufReadable, attributes(var))] -pub fn derive_mcbufreadable(input: TokenStream) -> TokenStream { +#[proc_macro_derive(AzaleaRead, attributes(var))] +pub fn derive_azalearead(input: TokenStream) -> TokenStream { let DeriveInput { ident, data, .. } = parse_macro_input!(input); - read::create_impl_mcbufreadable(&ident, &data).into() + read::create_impl_azalearead(&ident, &data).into() } -#[proc_macro_derive(McBufWritable, attributes(var))] -pub fn derive_mcbufwritable(input: TokenStream) -> TokenStream { +#[proc_macro_derive(AzaleaWrite, attributes(var))] +pub fn derive_azaleawrite(input: TokenStream) -> TokenStream { let DeriveInput { ident, data, .. } = parse_macro_input!(input); - write::create_impl_mcbufwritable(&ident, &data).into() + write::create_impl_azaleawrite(&ident, &data).into() } -#[proc_macro_derive(McBuf, attributes(var))] -pub fn derive_mcbuf(input: TokenStream) -> TokenStream { +#[proc_macro_derive(AzBuf, attributes(var, limit))] +pub fn derive_azbuf(input: TokenStream) -> TokenStream { let DeriveInput { ident, data, .. } = parse_macro_input!(input); - let writable = write::create_impl_mcbufwritable(&ident, &data); - let readable = read::create_impl_mcbufreadable(&ident, &data); + let writable = write::create_impl_azaleawrite(&ident, &data); + let readable = read::create_impl_azalearead(&ident, &data); quote! { #writable #readable diff --git a/azalea-buf/azalea-buf-macros/src/read.rs b/azalea-buf/azalea-buf-macros/src/read.rs index c5c484e7..c093d4a1 100644 --- a/azalea-buf/azalea-buf-macros/src/read.rs +++ b/azalea-buf/azalea-buf-macros/src/read.rs @@ -9,17 +9,38 @@ fn read_named_fields( .map(|f| { let field_name = &f.ident; let field_type = &f.ty; + + let is_variable_length = f.attrs.iter().any(|a| a.path().is_ident("var")); + let limit = f + .attrs + .iter() + .find(|a| a.path().is_ident("limit")) + .map(|a| { + a.parse_args::() + .unwrap() + .base10_parse::() + .unwrap() + }); + + if is_variable_length && limit.is_some() { + panic!("Fields cannot have both var and limit attributes"); + } + // do a different buf.write_* for each field depending on the type // if it's a string, use buf.write_string match field_type { syn::Type::Path(_) | syn::Type::Array(_) => { - if f.attrs.iter().any(|a| a.path().is_ident("var")) { + if is_variable_length { + quote! { + let #field_name = azalea_buf::AzaleaReadVar::azalea_read_var(buf)?; + } + } else if let Some(limit) = limit { quote! { - let #field_name = azalea_buf::McBufVarReadable::var_read_from(buf)?; + let #field_name = azalea_buf::AzaleaReadLimited::azalea_read_limited(buf, #limit)?; } } else { quote! { - let #field_name = azalea_buf::McBufReadable::read_from(buf)?; + let #field_name = azalea_buf::AzaleaRead::azalea_read(buf)?; } } } @@ -36,15 +57,15 @@ fn read_named_fields( (read_fields, read_field_names) } -pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { +pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { match data { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Fields::Named(FieldsNamed { named, .. }) => { let (read_fields, read_field_names) = read_named_fields(named); quote! { - impl azalea_buf::McBufReadable for #ident { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { + impl azalea_buf::AzaleaRead for #ident { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { #(#read_fields)* Ok(Self { #(#read_field_names: #read_field_names),* @@ -55,15 +76,15 @@ pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::Tok } syn::Fields::Unit => { quote! { - impl azalea_buf::McBufReadable for #ident { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { + impl azalea_buf::AzaleaRead for #ident { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { Ok(Self) } } } } _ => { - panic!("#[derive(McBuf)] can only be used on structs with named fields") + panic!("#[derive(AzBuf)] can only be used on structs with named fields") } }, syn::Data::Enum(syn::DataEnum { variants, .. }) => { @@ -108,13 +129,34 @@ pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::Tok syn::Fields::Unnamed(fields) => { let mut reader_code = quote! {}; for f in &fields.unnamed { - if f.attrs.iter().any(|attr| attr.path().is_ident("var")) { + let is_variable_length = + f.attrs.iter().any(|a| a.path().is_ident("var")); + let limit = + f.attrs + .iter() + .find(|a| a.path().is_ident("limit")) + .map(|a| { + a.parse_args::() + .unwrap() + .base10_parse::() + .unwrap() + }); + + if is_variable_length && limit.is_some() { + panic!("Fields cannot have both var and limit attributes"); + } + + if is_variable_length { + reader_code.extend(quote! { + Self::#variant_name(azalea_buf::AzaleaReadVar::azalea_read_var(buf)?), + }); + } else if let Some(limit) = limit { reader_code.extend(quote! { - Self::#variant_name(azalea_buf::McBufVarReadable::var_read_from(buf)?), + Self::#variant_name(azalea_buf::AzaleaReadLimited::azalea_read_limited(buf, #limit)?), }); } else { reader_code.extend(quote! { - Self::#variant_name(azalea_buf::McBufReadable::read_from(buf)?), + Self::#variant_name(azalea_buf::AzaleaRead::azalea_read(buf)?), }); } } @@ -139,15 +181,15 @@ pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::Tok let first_reader = first_reader.expect("There should be at least one variant"); quote! { - impl azalea_buf::McBufReadable for #ident { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { - let id = azalea_buf::McBufVarReadable::var_read_from(buf)?; - Self::read_from_id(buf, id) + impl azalea_buf::AzaleaRead for #ident { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + let id = azalea_buf::AzaleaReadVar::azalea_read_var(buf)?; + Self::azalea_read_id(buf, id) } } impl #ident { - pub fn read_from_id(buf: &mut std::io::Cursor<&[u8]>, id: u32) -> Result { + pub fn azalea_read_id(buf: &mut std::io::Cursor<&[u8]>, id: u32) -> Result { match id { #match_contents // you'd THINK this throws an error, but mojang decided to make it default for some reason @@ -157,6 +199,6 @@ pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::Tok } } } - _ => panic!("#[derive(McBuf)] can only be used on structs"), + _ => panic!("#[derive(AzBuf)] can only be used on structs"), } } diff --git a/azalea-buf/azalea-buf-macros/src/write.rs b/azalea-buf/azalea-buf-macros/src/write.rs index 4d31f39e..df461d59 100644 --- a/azalea-buf/azalea-buf-macros/src/write.rs +++ b/azalea-buf/azalea-buf-macros/src/write.rs @@ -19,11 +19,11 @@ fn write_named_fields( syn::Type::Path(_) | syn::Type::Array(_) => { if f.attrs.iter().any(|attr| attr.path().is_ident("var")) { quote! { - azalea_buf::McBufVarWritable::var_write_into(#ident_dot_field, buf)?; + azalea_buf::AzaleaWriteVar::azalea_write_var(#ident_dot_field, buf)?; } } else { quote! { - azalea_buf::McBufWritable::write_into(#ident_dot_field, buf)?; + azalea_buf::AzaleaWrite::azalea_write(#ident_dot_field, buf)?; } } } @@ -37,7 +37,7 @@ fn write_named_fields( quote! { #(#write_fields)* } } -pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { +pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { match data { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Fields::Named(FieldsNamed { named, .. }) => { @@ -45,8 +45,8 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok write_named_fields(named, Some(&Ident::new("self", Span::call_site()))); quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + impl azalea_buf::AzaleaWrite for #ident { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { #write_fields Ok(()) } @@ -55,15 +55,15 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok } syn::Fields::Unit => { quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + impl azalea_buf::AzaleaWrite for #ident { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { Ok(()) } } } } _ => { - panic!("#[derive(McBuf)] can only be used on structs with named fields") + panic!("#[derive(AzBuf)] can only be used on structs with named fields") } }, syn::Data::Enum(syn::DataEnum { variants, .. }) => { @@ -103,7 +103,7 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok // the variant number that we're going to write let write_the_variant = quote! { - azalea_buf::McBufVarWritable::var_write_into(&#variant_discrim, buf)?; + azalea_buf::AzaleaWriteVar::azalea_write_var(&#variant_discrim, buf)?; }; match &variant.fields { syn::Fields::Named(f) => { @@ -145,11 +145,11 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok params_code.extend(quote! { #param_ident, }); if f.attrs.iter().any(|attr| attr.path().is_ident("var")) { writers_code.extend(quote! { - azalea_buf::McBufVarWritable::var_write_into(#param_ident, buf)?; + azalea_buf::AzaleaWriteVar::azalea_write_var(#param_ident, buf)?; }); } else { writers_code.extend(quote! { - azalea_buf::McBufWritable::write_into(#param_ident, buf)?; + azalea_buf::AzaleaWrite::azalea_write(#param_ident, buf)?; }); } } @@ -161,7 +161,7 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok }); match_arms_without_id.extend(quote! { Self::#variant_name(data) => { - azalea_buf::McBufWritable::write_into(data, buf)?; + azalea_buf::AzaleaWrite::azalea_write(data, buf)?; } }); } @@ -169,8 +169,8 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok } if is_data_enum { quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + impl azalea_buf::AzaleaWrite for #ident { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { match self { #match_arms } @@ -189,14 +189,14 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok } else { // optimization: if it doesn't have data we can just do `as u32` quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - azalea_buf::McBufVarWritable::var_write_into(&(*self as u32), buf) + impl azalea_buf::AzaleaWrite for #ident { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + azalea_buf::AzaleaWriteVar::azalea_write_var(&(*self as u32), buf) } } } } } - _ => panic!("#[derive(McBuf)] can only be used on structs"), + _ => panic!("#[derive(AzBuf)] can only be used on structs"), } } diff --git a/azalea-buf/src/lib.rs b/azalea-buf/src/lib.rs index e1d1281f..ef3bd3a8 100755 --- a/azalea-buf/src/lib.rs +++ b/azalea-buf/src/lib.rs @@ -10,9 +10,9 @@ mod write; pub use azalea_buf_macros::*; pub use definitions::*; -pub use read::{BufReadError, McBufReadable, McBufVarReadable}; +pub use read::{AzaleaRead, AzaleaReadLimited, AzaleaReadVar, BufReadError}; pub use serializable_uuid::*; -pub use write::{McBufVarWritable, McBufWritable}; +pub use write::{AzaleaWrite, AzaleaWriteVar}; // const DEFAULT_NBT_QUOTA: u32 = 2097152; const MAX_STRING_LENGTH: u16 = 32767; @@ -27,110 +27,113 @@ mod tests { #[test] fn test_write_varint() { let mut buf = Vec::new(); - 0.var_write_into(&mut buf).unwrap(); + 0.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![0]); let mut buf = Vec::new(); - 1.var_write_into(&mut buf).unwrap(); + 1.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![1]); let mut buf = Vec::new(); - 2.var_write_into(&mut buf).unwrap(); + 2.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![2]); let mut buf = Vec::new(); - 127.var_write_into(&mut buf).unwrap(); + 127.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![127]); let mut buf = Vec::new(); - 128.var_write_into(&mut buf).unwrap(); + 128.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![128, 1]); let mut buf = Vec::new(); - 255.var_write_into(&mut buf).unwrap(); + 255.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![255, 1]); let mut buf = Vec::new(); - 25565.var_write_into(&mut buf).unwrap(); + 25565.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![221, 199, 1]); let mut buf = Vec::new(); - 2097151.var_write_into(&mut buf).unwrap(); + 2097151.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![255, 255, 127]); let mut buf = Vec::new(); - 2147483647.var_write_into(&mut buf).unwrap(); + 2147483647.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![255, 255, 255, 255, 7]); let mut buf = Vec::new(); - (-1).var_write_into(&mut buf).unwrap(); + (-1).azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![255, 255, 255, 255, 15]); let mut buf = Vec::new(); - (-2147483648).var_write_into(&mut buf).unwrap(); + (-2147483648).azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![128, 128, 128, 128, 8]); } #[test] fn test_read_varint() { // let buf = &mut &vec![0][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 0); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 0); let buf = vec![0]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 0); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 0); // let buf = &mut &vec![1][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 1); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 1); let buf = vec![1]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 1); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 1); // let buf = &mut &vec![2][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 2); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 2); let buf = vec![2]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 2); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 2); // let buf = &mut &vec![127][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 127); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 127); let buf = vec![127]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 127); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 127); // let buf = &mut &vec![128, 1][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 128); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 128); let buf = vec![128, 1]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 128); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 128); // let buf = &mut &vec![255, 1][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 255); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 255); let buf = vec![255, 1]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 255); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 255); // let buf = &mut &vec![221, 199, 1][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 25565); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 25565); let buf = vec![221, 199, 1]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 25565); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 25565); // let buf = &mut &vec![255, 255, 127][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 2097151); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 2097151); let buf = vec![255, 255, 127]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 2097151); + assert_eq!( + i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), + 2097151 + ); // let buf = &mut &vec![255, 255, 255, 255, 7][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), 2147483647); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), 2147483647); let buf = vec![255, 255, 255, 255, 7]; assert_eq!( - i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), + i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 2147483647 ); // let buf = &mut &vec![255, 255, 255, 255, 15][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), -1); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), -1); let buf = vec![255, 255, 255, 255, 15]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), -1); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), -1); // let buf = &mut &vec![128, 128, 128, 128, 8][..]; - // assert_eq!(i32::var_read_from(buf).unwrap(), -2147483648); + // assert_eq!(i32::azalea_read_var(buf).unwrap(), -2147483648); let buf = vec![128, 128, 128, 128, 8]; assert_eq!( - i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), + i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), -2147483648 ); } @@ -138,21 +141,21 @@ mod tests { #[test] fn test_read_varint_longer() { let buf = vec![138, 56, 0, 135, 56, 123]; - assert_eq!(i32::var_read_from(&mut Cursor::new(&buf)).unwrap(), 7178); + assert_eq!(i32::azalea_read_var(&mut Cursor::new(&buf)).unwrap(), 7178); } #[test] fn test_write_varlong() { let mut buf = Vec::new(); - 0u64.var_write_into(&mut buf).unwrap(); + 0u64.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![0]); let mut buf = Vec::new(); - 1u64.var_write_into(&mut buf).unwrap(); + 1u64.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![1]); let mut buf = Vec::new(); - 9223372036854775807u64.var_write_into(&mut buf).unwrap(); + 9223372036854775807u64.azalea_write_var(&mut buf).unwrap(); assert_eq!(buf, vec![255, 255, 255, 255, 255, 255, 255, 255, 127]); } @@ -161,20 +164,20 @@ mod tests { let original_vec = vec!["a".to_string(), "bc".to_string(), "def".to_string()]; let mut buf = Vec::new(); - original_vec.write_into(&mut buf).unwrap(); + original_vec.azalea_write(&mut buf).unwrap(); dbg!(&buf); - let result = Vec::::read_from(&mut Cursor::new(&buf)).unwrap(); + let result = Vec::::azalea_read(&mut Cursor::new(&buf)).unwrap(); assert_eq!(result, original_vec); } #[test] fn test_int_id_list() { let mut buf = Vec::new(); - vec![1, 2, 3].var_write_into(&mut buf).unwrap(); + vec![1, 2, 3].azalea_write_var(&mut buf).unwrap(); - let result = Vec::::var_read_from(&mut Cursor::new(&buf)).unwrap(); + let result = Vec::::azalea_read_var(&mut Cursor::new(&buf)).unwrap(); assert_eq!(result, vec![1, 2, 3]); } @@ -186,9 +189,9 @@ mod tests { ("def".to_string(), 456), ]); let mut buf = Vec::new(); - original_map.var_write_into(&mut buf).unwrap(); + original_map.azalea_write_var(&mut buf).unwrap(); - let result = HashMap::::var_read_from(&mut Cursor::new(&buf)).unwrap(); + let result = HashMap::::azalea_read_var(&mut Cursor::new(&buf)).unwrap(); assert_eq!(result, original_map); } @@ -196,8 +199,8 @@ mod tests { #[test] fn test_long() { let mut buf: Vec = Vec::new(); - 123456u64.write_into(&mut buf).unwrap(); + 123456u64.azalea_write(&mut buf).unwrap(); - assert_eq!(u64::read_from(&mut Cursor::new(&buf)).unwrap(), 123456); + assert_eq!(u64::azalea_read(&mut Cursor::new(&buf)).unwrap(), 123456); } } diff --git a/azalea-buf/src/read.rs b/azalea-buf/src/read.rs index 8e406acb..4353539a 100755 --- a/azalea-buf/src/read.rs +++ b/azalea-buf/src/read.rs @@ -81,7 +81,7 @@ fn read_bytes<'a>(buf: &'a mut Cursor<&[u8]>, length: usize) -> Result<&'a [u8], } fn read_utf_with_len(buf: &mut Cursor<&[u8]>, max_length: u32) -> Result { - let length = u32::var_read_from(buf)?; + let length = u32::azalea_read_var(buf)?; // i don't know why it's multiplied by 4 but it's like that in mojang's code so if length > max_length * 4 { return Err(BufReadError::StringLengthTooLong { @@ -105,30 +105,40 @@ fn read_utf_with_len(buf: &mut Cursor<&[u8]>, max_length: u32) -> Result) -> Result; + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result; } -pub trait McBufVarReadable +pub trait AzaleaReadVar where Self: Sized, { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result; + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result; } -impl McBufReadable for i32 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +// note that there's no Write equivalent for this trait since we don't really +// care if we're writing over the limit (and maybe we already know that the +// server implementation accepts it) +pub trait AzaleaReadLimited +where + Self: Sized, +{ + fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result; +} + +impl AzaleaRead for i32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_i32::()?) } } -impl McBufVarReadable for i32 { +impl AzaleaReadVar for i32 { // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67 /// Read a single varint from the reader and return the value - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { let mut buffer = [0]; let mut ans = 0; for i in 0..5 { @@ -142,9 +152,9 @@ impl McBufVarReadable for i32 { } } -impl McBufVarReadable for i64 { +impl AzaleaReadVar for i64 { // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L54 - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { let mut buffer = [0]; let mut ans = 0; for i in 0..10 { @@ -158,14 +168,14 @@ impl McBufVarReadable for i64 { Ok(ans) } } -impl McBufVarReadable for u64 { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - i64::var_read_from(buf).map(|i| i as u64) +impl AzaleaReadVar for u64 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + i64::azalea_read_var(buf).map(|i| i as u64) } } -impl McBufReadable for UnsizedByteArray { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for UnsizedByteArray { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { // read to end of the buffer let data = buf.get_ref()[buf.position() as usize..].to_vec(); buf.set_position((buf.position()) + data.len() as u64); @@ -173,111 +183,114 @@ impl McBufReadable for UnsizedByteArray { } } -impl McBufReadable for Vec { - default fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = u32::var_read_from(buf)? as usize; +impl AzaleaRead for Vec { + default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let length = u32::azalea_read_var(buf)? as usize; // we limit the capacity to not get exploited into allocating a bunch let mut contents = Vec::with_capacity(usize::min(length, 65536)); for _ in 0..length { - contents.push(T::read_from(buf)?); + contents.push(T::azalea_read(buf)?); } Ok(contents) } } -impl McBufReadable for HashMap { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = i32::var_read_from(buf)? as usize; +impl AzaleaRead for HashMap { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let length = i32::azalea_read_var(buf)? as usize; let mut contents = HashMap::with_capacity(usize::min(length, 65536)); for _ in 0..length { - contents.insert(K::read_from(buf)?, V::read_from(buf)?); + contents.insert(K::azalea_read(buf)?, V::azalea_read(buf)?); } Ok(contents) } } -impl McBufVarReadable - for HashMap -{ - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = i32::var_read_from(buf)? as usize; +impl AzaleaReadVar for HashMap { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + let length = i32::azalea_read_var(buf)? as usize; let mut contents = HashMap::with_capacity(usize::min(length, 65536)); for _ in 0..length { - contents.insert(K::read_from(buf)?, V::var_read_from(buf)?); + contents.insert(K::azalea_read(buf)?, V::azalea_read_var(buf)?); } Ok(contents) } } -impl McBufReadable for Vec { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = i32::var_read_from(buf)? as usize; +impl AzaleaRead for Vec { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let length = i32::azalea_read_var(buf)? as usize; read_bytes(buf, length).map(|b| b.to_vec()) } } -impl McBufReadable for String { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for String { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { read_utf_with_len(buf, MAX_STRING_LENGTH.into()) } } +impl AzaleaReadLimited for String { + fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result { + read_utf_with_len(buf, limit as u32) + } +} -impl McBufReadable for u32 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(i32::read_from(buf)? as u32) +impl AzaleaRead for u32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + Ok(i32::azalea_read(buf)? as u32) } } -impl McBufVarReadable for u32 { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(i32::var_read_from(buf)? as u32) +impl AzaleaReadVar for u32 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + Ok(i32::azalea_read_var(buf)? as u32) } } -impl McBufReadable for u16 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - i16::read_from(buf).map(|i| i as u16) +impl AzaleaRead for u16 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + i16::azalea_read(buf).map(|i| i as u16) } } -impl McBufReadable for i16 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for i16 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_i16::()?) } } -impl McBufVarReadable for u16 { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(i32::var_read_from(buf)? as u16) +impl AzaleaReadVar for u16 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + Ok(i32::azalea_read_var(buf)? as u16) } } -impl McBufVarReadable for Vec { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = i32::var_read_from(buf)? as usize; +impl AzaleaReadVar for Vec { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + let length = i32::azalea_read_var(buf)? as usize; let mut contents = Vec::with_capacity(usize::min(length, 65536)); for _ in 0..length { - contents.push(T::var_read_from(buf)?); + contents.push(T::azalea_read_var(buf)?); } Ok(contents) } } -impl McBufReadable for i64 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for i64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_i64::()?) } } -impl McBufReadable for u64 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - i64::read_from(buf).map(|i| i as u64) +impl AzaleaRead for u64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + i64::azalea_read(buf).map(|i| i as u64) } } -impl McBufReadable for bool { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let byte = u8::read_from(buf)?; +impl AzaleaRead for bool { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let byte = u8::azalea_read(buf)?; if byte > 1 { warn!("Boolean value was not 0 or 1, but {}", byte); } @@ -285,46 +298,46 @@ impl McBufReadable for bool { } } -impl McBufReadable for u8 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for u8 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_u8()?) } } -impl McBufReadable for i8 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - u8::read_from(buf).map(|i| i as i8) +impl AzaleaRead for i8 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + u8::azalea_read(buf).map(|i| i as i8) } } -impl McBufReadable for f32 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for f32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_f32::()?) } } -impl McBufReadable for f64 { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for f64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(buf.read_f64::()?) } } -impl McBufReadable for Option { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let present = bool::read_from(buf)?; +impl AzaleaRead for Option { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let present = bool::azalea_read(buf)?; Ok(if present { - Some(T::read_from(buf)?) + Some(T::azalea_read(buf)?) } else { None }) } } -impl McBufVarReadable for Option { - fn var_read_from(buf: &mut Cursor<&[u8]>) -> Result { - let present = bool::read_from(buf)?; +impl AzaleaReadVar for Option { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result { + let present = bool::azalea_read(buf)?; Ok(if present { - Some(T::var_read_from(buf)?) + Some(T::azalea_read_var(buf)?) } else { None }) @@ -332,11 +345,11 @@ impl McBufVarReadable for Option { } // [String; 4] -impl McBufReadable for [T; N] { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for [T; N] { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { let mut contents = Vec::with_capacity(N); for _ in 0..N { - contents.push(T::read_from(buf)?); + contents.push(T::azalea_read(buf)?); } contents.try_into().map_err(|_| { unreachable!("Panic is not possible since the Vec is the same size as the array") @@ -344,14 +357,14 @@ impl McBufReadable for [T; N] { } } -impl McBufReadable for simdnbt::owned::NbtTag { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for simdnbt::owned::NbtTag { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)?) } } -impl McBufReadable for simdnbt::owned::NbtCompound { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for simdnbt::owned::NbtCompound { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { match simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)? { simdnbt::owned::NbtTag::Compound(compound) => Ok(compound), _ => Err(BufReadError::Custom("Expected compound tag".to_string())), @@ -359,17 +372,17 @@ impl McBufReadable for simdnbt::owned::NbtCompound { } } -impl McBufReadable for simdnbt::owned::Nbt { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for simdnbt::owned::Nbt { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(simdnbt::owned::read_unnamed(buf)?) } } -impl McBufReadable for Box +impl AzaleaRead for Box where - T: McBufReadable, + T: AzaleaRead, { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(Box::new(T::read_from(buf)?)) + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + Ok(Box::new(T::azalea_read(buf)?)) } } diff --git a/azalea-buf/src/serializable_uuid.rs b/azalea-buf/src/serializable_uuid.rs index d4ec0315..53eccbbb 100755 --- a/azalea-buf/src/serializable_uuid.rs +++ b/azalea-buf/src/serializable_uuid.rs @@ -2,7 +2,7 @@ use std::io::{Cursor, Write}; use uuid::Uuid; -use crate::{read::BufReadError, McBufReadable, McBufWritable}; +use crate::{read::BufReadError, AzaleaRead, AzaleaWrite}; pub trait SerializableUuid { fn to_int_array(&self) -> [u32; 4]; @@ -34,24 +34,24 @@ impl SerializableUuid for Uuid { } } -impl McBufReadable for Uuid { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for Uuid { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(Uuid::from_int_array([ - u32::read_from(buf)?, - u32::read_from(buf)?, - u32::read_from(buf)?, - u32::read_from(buf)?, + u32::azalea_read(buf)?, + u32::azalea_read(buf)?, + u32::azalea_read(buf)?, + u32::azalea_read(buf)?, ])) } } -impl McBufWritable for Uuid { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for Uuid { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let [a, b, c, d] = self.to_int_array(); - a.write_into(buf)?; - b.write_into(buf)?; - c.write_into(buf)?; - d.write_into(buf)?; + a.azalea_write(buf)?; + b.azalea_write(buf)?; + c.azalea_write(buf)?; + d.azalea_write(buf)?; Ok(()) } } @@ -79,10 +79,10 @@ mod tests { fn read_write() { let u = Uuid::parse_str("6536bfed-8695-48fd-83a1-ecd24cf2a0fd").unwrap(); let mut buf = Vec::new(); - u.write_into(&mut buf).unwrap(); + u.azalea_write(&mut buf).unwrap(); println!("{buf:?}"); assert_eq!(buf.len(), 16); - let u2 = Uuid::read_from(&mut Cursor::new(&buf)).unwrap(); + let u2 = Uuid::azalea_read(&mut Cursor::new(&buf)).unwrap(); assert_eq!(u, u2); } } diff --git a/azalea-buf/src/write.rs b/azalea-buf/src/write.rs index 49215a5a..1092586d 100755 --- a/azalea-buf/src/write.rs +++ b/azalea-buf/src/write.rs @@ -16,26 +16,26 @@ fn write_utf_with_len( len ); } - string.as_bytes().to_vec().write_into(buf)?; + string.as_bytes().to_vec().azalea_write(buf)?; Ok(()) } -pub trait McBufWritable { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; +pub trait AzaleaWrite { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } -pub trait McBufVarWritable { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; +pub trait AzaleaWriteVar { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } -impl McBufWritable for i32 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for i32 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_i32::(buf, *self) } } -impl McBufVarWritable for i32 { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWriteVar for i32 { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut buffer = [0]; let mut value = *self; if value == 0 { @@ -53,85 +53,85 @@ impl McBufVarWritable for i32 { } } -impl McBufWritable for UnsizedByteArray { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for UnsizedByteArray { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_all(self) } } -impl McBufWritable for Vec { - default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self[..].write_into(buf) +impl AzaleaWrite for Vec { + default fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self[..].azalea_write(buf) } } -impl McBufWritable for [T] { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (self.len() as u32).var_write_into(buf)?; +impl AzaleaWrite for [T] { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.len() as u32).azalea_write_var(buf)?; for item in self { - T::write_into(item, buf)?; + T::azalea_write(item, buf)?; } Ok(()) } } -impl McBufWritable for HashMap { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u32::var_write_into(&(self.len() as u32), buf)?; +impl AzaleaWrite for HashMap { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u32::azalea_write_var(&(self.len() as u32), buf)?; for (key, value) in self { - key.write_into(buf)?; - value.write_into(buf)?; + key.azalea_write(buf)?; + value.azalea_write(buf)?; } Ok(()) } } -impl McBufVarWritable for HashMap { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u32::var_write_into(&(self.len() as u32), buf)?; +impl AzaleaWriteVar for HashMap { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u32::azalea_write_var(&(self.len() as u32), buf)?; for (key, value) in self { - key.write_into(buf)?; - value.var_write_into(buf)?; + key.azalea_write(buf)?; + value.azalea_write_var(buf)?; } Ok(()) } } -impl McBufWritable for Vec { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (self.len() as u32).var_write_into(buf)?; +impl AzaleaWrite for Vec { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.len() as u32).azalea_write_var(buf)?; buf.write_all(self) } } -impl McBufWritable for String { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for String { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { write_utf_with_len(buf, self, MAX_STRING_LENGTH.into()) } } -impl McBufWritable for &str { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for &str { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { write_utf_with_len(buf, self, MAX_STRING_LENGTH.into()) } } -impl McBufWritable for u32 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i32::write_into(&(*self as i32), buf) +impl AzaleaWrite for u32 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i32::azalea_write(&(*self as i32), buf) } } -impl McBufVarWritable for u32 { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i32::var_write_into(&(*self as i32), buf) +impl AzaleaWriteVar for u32 { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i32::azalea_write_var(&(*self as i32), buf) } } -impl McBufVarWritable for i64 { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWriteVar for i64 { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut buffer = [0]; let mut value = *self; if value == 0 { @@ -149,146 +149,146 @@ impl McBufVarWritable for i64 { } } -impl McBufVarWritable for u64 { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i64::var_write_into(&(*self as i64), buf) +impl AzaleaWriteVar for u64 { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i64::azalea_write_var(&(*self as i64), buf) } } -impl McBufWritable for u16 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i16::write_into(&(*self as i16), buf) +impl AzaleaWrite for u16 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i16::azalea_write(&(*self as i16), buf) } } -impl McBufVarWritable for u16 { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i32::var_write_into(&(*self as i32), buf) +impl AzaleaWriteVar for u16 { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i32::azalea_write_var(&(*self as i32), buf) } } -impl McBufVarWritable for Vec { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u32::var_write_into(&(self.len() as u32), buf)?; +impl AzaleaWriteVar for Vec { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u32::azalea_write_var(&(self.len() as u32), buf)?; for i in self { - i.var_write_into(buf)?; + i.azalea_write_var(buf)?; } Ok(()) } } -impl McBufWritable for u8 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for u8 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_u8(buf, *self) } } -impl McBufWritable for i16 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for i16 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_i16::(buf, *self) } } -impl McBufWritable for i64 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for i64 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_i64::(buf, *self) } } -impl McBufWritable for u64 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - i64::write_into(&(*self as i64), buf) +impl AzaleaWrite for u64 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + i64::azalea_write(&(*self as i64), buf) } } -impl McBufWritable for bool { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for bool { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let byte = u8::from(*self); - byte.write_into(buf) + byte.azalea_write(buf) } } -impl McBufWritable for i8 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (*self as u8).write_into(buf) +impl AzaleaWrite for i8 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (*self as u8).azalea_write(buf) } } -impl McBufWritable for f32 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for f32 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_f32::(buf, *self) } } -impl McBufWritable for f64 { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for f64 { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { WriteBytesExt::write_f64::(buf, *self) } } -impl McBufWritable for Option { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for Option { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { if let Some(s) = self { - true.write_into(buf)?; - s.write_into(buf)?; + true.azalea_write(buf)?; + s.azalea_write(buf)?; } else { - false.write_into(buf)?; + false.azalea_write(buf)?; }; Ok(()) } } -impl McBufVarWritable for Option { - fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWriteVar for Option { + fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { if let Some(s) = self { - true.write_into(buf)?; - s.var_write_into(buf)?; + true.azalea_write(buf)?; + s.azalea_write_var(buf)?; } else { - false.write_into(buf)?; + false.azalea_write(buf)?; }; Ok(()) } } // [T; N] -impl McBufWritable for [T; N] { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for [T; N] { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for i in self { - i.write_into(buf)?; + i.azalea_write(buf)?; } Ok(()) } } -impl McBufWritable for simdnbt::owned::NbtTag { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for simdnbt::owned::NbtTag { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut data = Vec::new(); self.write(&mut data); buf.write_all(&data) } } -impl McBufWritable for simdnbt::owned::NbtCompound { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for simdnbt::owned::NbtCompound { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut data = Vec::new(); simdnbt::owned::NbtTag::Compound(self.clone()).write(&mut data); buf.write_all(&data) } } -impl McBufWritable for simdnbt::owned::Nbt { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for simdnbt::owned::Nbt { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut data = Vec::new(); self.write_unnamed(&mut data); buf.write_all(&data) } } -impl McBufWritable for Box +impl AzaleaWrite for Box where - T: McBufWritable, + T: AzaleaWrite, { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - T::write_into(&**self, buf) + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + T::azalea_write(&**self, buf) } } diff --git a/azalea-chat/Cargo.toml b/azalea-chat/Cargo.toml index 370a8862..b4f38ac3 100644 --- a/azalea-chat/Cargo.toml +++ b/azalea-chat/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-chat" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-chat" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-chat/src/component.rs b/azalea-chat/src/component.rs index 43614c77..86738b26 100755 --- a/azalea-chat/src/component.rs +++ b/azalea-chat/src/component.rs @@ -1,7 +1,7 @@ use std::{fmt::Display, sync::LazyLock}; #[cfg(feature = "azalea-buf")] -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; use serde::{de, Deserialize, Deserializer, Serialize}; #[cfg(feature = "simdnbt")] use simdnbt::{Deserialize as _, FromNbtTag as _, Serialize as _}; @@ -455,8 +455,8 @@ impl From<&simdnbt::Mutf8Str> for FormattedText { #[cfg(feature = "azalea-buf")] #[cfg(feature = "simdnbt")] -impl McBufReadable for FormattedText { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { +impl AzaleaRead for FormattedText { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { let nbt = simdnbt::borrow::read_optional_tag(buf)?; if let Some(nbt) = nbt { FormattedText::from_nbt_tag(nbt.as_tag()).ok_or(BufReadError::Custom( @@ -470,8 +470,8 @@ impl McBufReadable for FormattedText { #[cfg(feature = "azalea-buf")] #[cfg(feature = "simdnbt")] -impl McBufWritable for FormattedText { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for FormattedText { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { let mut out = Vec::new(); simdnbt::owned::BaseNbt::write_unnamed(&(self.clone().to_compound().into()), &mut out); buf.write_all(&out) diff --git a/azalea-chat/src/numbers.rs b/azalea-chat/src/numbers.rs index a5a88c4f..161f1177 100644 --- a/azalea-chat/src/numbers.rs +++ b/azalea-chat/src/numbers.rs @@ -4,7 +4,7 @@ use std::io::{Cursor, Write}; #[cfg(feature = "azalea-buf")] -use azalea_buf::{McBufReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaWrite}; use azalea_registry::NumberFormatKind; use simdnbt::owned::Nbt; @@ -18,33 +18,33 @@ pub enum NumberFormat { } #[cfg(feature = "azalea-buf")] -impl McBufReadable for NumberFormat { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let kind = NumberFormatKind::read_from(buf)?; +impl AzaleaRead for NumberFormat { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let kind = NumberFormatKind::azalea_read(buf)?; match kind { NumberFormatKind::Blank => Ok(NumberFormat::Blank), NumberFormatKind::Styled => Ok(NumberFormat::Styled { style: simdnbt::owned::read(buf)?, }), NumberFormatKind::Fixed => Ok(NumberFormat::Fixed { - value: FormattedText::read_from(buf)?, + value: FormattedText::azalea_read(buf)?, }), } } } #[cfg(feature = "azalea-buf")] -impl McBufWritable for NumberFormat { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for NumberFormat { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { - NumberFormat::Blank => NumberFormatKind::Blank.write_into(buf)?, + NumberFormat::Blank => NumberFormatKind::Blank.azalea_write(buf)?, NumberFormat::Styled { style } => { - NumberFormatKind::Styled.write_into(buf)?; - style.write_into(buf)?; + NumberFormatKind::Styled.azalea_write(buf)?; + style.azalea_write(buf)?; } NumberFormat::Fixed { value } => { - NumberFormatKind::Fixed.write_into(buf)?; - value.write_into(buf)?; + NumberFormatKind::Fixed.azalea_write(buf)?; + value.azalea_write(buf)?; } } Ok(()) diff --git a/azalea-chat/src/style.rs b/azalea-chat/src/style.rs index e147bc97..fd2a58dd 100755 --- a/azalea-chat/src/style.rs +++ b/azalea-chat/src/style.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, fmt, sync::LazyLock}; #[cfg(feature = "azalea-buf")] -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use serde::{ser::SerializeStruct, Serialize, Serializer}; use serde_json::Value; #[cfg(feature = "simdnbt")] @@ -100,7 +100,7 @@ impl Ansi { } #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -#[cfg_attr(feature = "azalea-buf", derive(McBuf))] +#[cfg_attr(feature = "azalea-buf", derive(AzBuf))] pub enum ChatFormatting { Black, DarkBlue, diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml index ee1e400a..3746a076 100644 --- a/azalea-client/Cargo.toml +++ b/azalea-client/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-client" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-client" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-client/src/attack.rs b/azalea-client/src/attack.rs index a28f800d..b1b36b69 100644 --- a/azalea-client/src/attack.rs +++ b/azalea-client/src/attack.rs @@ -4,9 +4,7 @@ use azalea_entity::{ update_bounding_box, Attributes, Physics, }; use azalea_physics::PhysicsSet; -use azalea_protocol::packets::game::serverbound_interact_packet::{ - self, ServerboundInteractPacket, -}; +use azalea_protocol::packets::game::s_interact::{self, ServerboundInteract}; use azalea_world::MinecraftEntityId; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -85,15 +83,14 @@ pub fn handle_attack_event( swing_arm_event.send(SwingArmEvent { entity: event.entity, }); - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundInteractPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundInteract { entity_id: *event.target, - action: serverbound_interact_packet::ActionType::Attack, + action: s_interact::ActionType::Attack, using_secondary_action: **sneaking, - } - .get(), - }); + }, + )); // we can't attack if we're in spectator mode but it still sends the attack // packet diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 80c52baf..de0b8a7d 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -6,12 +6,15 @@ use std::{ }; use azalea_chat::FormattedText; -use azalea_protocol::packets::game::{ - clientbound_disguised_chat_packet::ClientboundDisguisedChatPacket, - clientbound_player_chat_packet::ClientboundPlayerChatPacket, - clientbound_system_chat_packet::ClientboundSystemChatPacket, - serverbound_chat_command_packet::ServerboundChatCommandPacket, - serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket}, +use azalea_protocol::packets::{ + game::{ + c_disguised_chat::ClientboundDisguisedChat, + c_player_chat::ClientboundPlayerChat, + c_system_chat::ClientboundSystemChat, + s_chat::{LastSeenMessagesUpdate, ServerboundChat}, + s_chat_command::ServerboundChatCommand, + }, + Packet, }; use bevy_app::{App, Plugin, Update}; use bevy_ecs::{ @@ -30,9 +33,9 @@ use crate::{ /// A chat packet, either a system message or a chat message. #[derive(Debug, Clone, PartialEq)] pub enum ChatPacket { - System(Arc), - Player(Arc), - Disguised(Arc), + System(Arc), + Player(Arc), + Disguised(Arc), } macro_rules! regex { @@ -111,10 +114,10 @@ impl ChatPacket { self.split_sender_and_content().1 } - /// Create a new ChatPacket from a string. This is meant to be used as a + /// Create a new Chat from a string. This is meant to be used as a /// convenience function for testing. pub fn new(message: &str) -> Self { - ChatPacket::System(Arc::new(ClientboundSystemChatPacket { + ChatPacket::System(Arc::new(ClientboundSystemChat { content: FormattedText::from(message), overlay: false, })) @@ -141,7 +144,7 @@ impl Client { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: message.to_string(), - kind: ChatPacketKind::Message, + kind: ChatKind::Message, }); self.run_schedule_sender.send(()).unwrap(); } @@ -152,7 +155,7 @@ impl Client { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: command.to_string(), - kind: ChatPacketKind::Command, + kind: ChatKind::Command, }); self.run_schedule_sender.send(()).unwrap(); } @@ -215,13 +218,13 @@ pub fn handle_send_chat_event( send_chat_kind_events.send(SendChatKindEvent { entity: event.entity, content: event.content[1..].to_string(), - kind: ChatPacketKind::Command, + kind: ChatKind::Command, }); } else { send_chat_kind_events.send(SendChatKindEvent { entity: event.entity, content: event.content.clone(), - kind: ChatPacketKind::Message, + kind: ChatKind::Message, }); } } @@ -240,11 +243,11 @@ pub fn handle_send_chat_event( pub struct SendChatKindEvent { pub entity: Entity, pub content: String, - pub kind: ChatPacketKind, + pub kind: ChatKind, } /// A kind of chat packet, either a chat message or a command. -pub enum ChatPacketKind { +pub enum ChatKind { Message, Command, } @@ -261,7 +264,7 @@ pub fn handle_send_chat_kind_event( .take(256) .collect::(); let packet = match event.kind { - ChatPacketKind::Message => ServerboundChatPacket { + ChatKind::Message => ServerboundChat { message: content, timestamp: SystemTime::now() .duration_since(UNIX_EPOCH) @@ -273,17 +276,14 @@ pub fn handle_send_chat_kind_event( signature: None, last_seen_messages: LastSeenMessagesUpdate::default(), } - .get(), - ChatPacketKind::Command => { + .into_variant(), + ChatKind::Command => { // TODO: chat signing - ServerboundChatCommandPacket { command: content }.get() + ServerboundChatCommand { command: content }.into_variant() } }; - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet, - }); + send_packet_events.send(SendPacketEvent::new(event.entity, packet)); } } diff --git a/azalea-client/src/chunks.rs b/azalea-client/src/chunks.rs index 40e295aa..7056efa4 100644 --- a/azalea-client/src/chunks.rs +++ b/azalea-client/src/chunks.rs @@ -10,8 +10,8 @@ use std::{ use azalea_core::position::ChunkPos; use azalea_protocol::packets::game::{ - clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, - serverbound_chunk_batch_received_packet::ServerboundChunkBatchReceivedPacket, + c_level_chunk_with_light::ClientboundLevelChunkWithLight, + s_chunk_batch_received::ServerboundChunkBatchReceived, }; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -51,7 +51,7 @@ impl Plugin for ChunkPlugin { #[derive(Event)] pub struct ReceiveChunkEvent { pub entity: Entity, - pub packet: ClientboundLevelChunkWithLightPacket, + pub packet: ClientboundLevelChunkWithLight, } #[derive(Component, Clone, Debug)] @@ -159,13 +159,12 @@ pub fn handle_chunk_batch_finished_event( if let Ok(mut chunk_batch_info) = query.get_mut(event.entity) { chunk_batch_info.batch_finished(event.batch_size); let desired_chunks_per_tick = chunk_batch_info.desired_chunks_per_tick(); - send_packets.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundChunkBatchReceivedPacket { + send_packets.send(SendPacketEvent::new( + event.entity, + ServerboundChunkBatchReceived { desired_chunks_per_tick, - } - .get(), - }); + }, + )); } } } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 9083a80b..5158eedf 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -17,24 +17,21 @@ use azalea_entity::{ }; use azalea_physics::PhysicsPlugin; use azalea_protocol::{ + common::client_information::ClientInformation, connect::{Connection, ConnectionError, Proxy}, packets::{ - configuration::{ - serverbound_client_information_packet::ClientInformation, - ClientboundConfigurationPacket, ServerboundConfigurationPacket, - }, + self, + config::{ClientboundConfigPacket, ServerboundConfigPacket}, game::ServerboundGamePacket, - handshaking::{ - client_intention_packet::ClientIntentionPacket, ClientboundHandshakePacket, + handshake::{ + s_intention::ServerboundIntention, ClientboundHandshakePacket, ServerboundHandshakePacket, }, login::{ - serverbound_hello_packet::ServerboundHelloPacket, - serverbound_key_packet::ServerboundKeyPacket, - serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket, - ClientboundLoginPacket, + s_hello::ServerboundHello, s_key::ServerboundKey, + s_login_acknowledged::ServerboundLoginAcknowledged, ClientboundLoginPacket, }, - ClientIntention, ConnectionProtocol, PROTOCOL_VERSION, + ClientIntention, ConnectionProtocol, Packet, PROTOCOL_VERSION, }, resolver, ServerAddress, }; @@ -347,21 +344,18 @@ impl Client { address: &ServerAddress, ) -> Result< ( - Connection, + Connection, GameProfile, ), JoinError, > { // handshake - conn.write( - ClientIntentionPacket { - protocol_version: PROTOCOL_VERSION, - hostname: address.host.clone(), - port: address.port, - intention: ClientIntention::Login, - } - .get(), - ) + conn.write(ServerboundIntention { + protocol_version: PROTOCOL_VERSION, + hostname: address.host.clone(), + port: address.port, + intention: ClientIntention::Login, + }) .await?; let mut conn = conn.login(); @@ -374,15 +368,12 @@ impl Client { )); // login - conn.write( - ServerboundHelloPacket { - name: account.username.clone(), - // TODO: pretty sure this should generate an offline-mode uuid instead of just - // Uuid::default() - profile_id: account.uuid.unwrap_or_default(), - } - .get(), - ) + conn.write(ServerboundHello { + name: account.username.clone(), + // TODO: pretty sure this should generate an offline-mode uuid instead of just + // Uuid::default() + profile_id: account.uuid.unwrap_or_default(), + }) .await?; let (conn, profile) = loop { @@ -442,13 +433,10 @@ impl Client { } } - conn.write( - ServerboundKeyPacket { - key_bytes: e.encrypted_public_key, - encrypted_challenge: e.encrypted_challenge, - } - .get(), - ) + conn.write(ServerboundKey { + key_bytes: e.encrypted_public_key, + encrypted_challenge: e.encrypted_challenge, + }) .await?; conn.set_encryption_key(e.secret_key); @@ -462,8 +450,7 @@ impl Client { "Got profile {:?}. handshake is finished and we're now switching to the configuration state", p.game_profile ); - conn.write(ServerboundLoginAcknowledgedPacket {}.get()) - .await?; + conn.write(ServerboundLoginAcknowledged {}).await?; break (conn.configuration(), p.game_profile); } ClientboundLoginPacket::LoginDisconnect(p) => { @@ -477,6 +464,13 @@ impl Client { } ClientboundLoginPacket::CookieRequest(p) => { debug!("Got cookie request {:?}", p); + + conn.write(packets::login::ServerboundCookieResponse { + key: p.key, + // cookies aren't implemented + payload: None, + }) + .await?; } } }; @@ -493,8 +487,9 @@ impl Client { /// Write a packet directly to the server. pub fn write_packet( &self, - packet: ServerboundGamePacket, + packet: impl Packet, ) -> Result<(), crate::raw_connection::WritePacketError> { + let packet = packet.into_variant(); self.raw_connection_mut(&mut self.ecs.lock()) .write_packet(packet) } @@ -605,7 +600,7 @@ impl Client { "Sending client information (already logged in): {:?}", client_information ); - self.write_packet(azalea_protocol::packets::game::serverbound_client_information_packet::ServerboundClientInformationPacket { information: client_information.clone() }.get())?; + self.write_packet(azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() })?; } Ok(()) diff --git a/azalea-client/src/configuration.rs b/azalea-client/src/configuration.rs index 99b97f60..bfaa36f0 100644 --- a/azalea-client/src/configuration.rs +++ b/azalea-client/src/configuration.rs @@ -1,17 +1,16 @@ -use azalea_buf::McBufWritable; +use azalea_buf::AzaleaWrite; use azalea_core::resource_location::ResourceLocation; -use azalea_protocol::packets::configuration::{ - serverbound_client_information_packet::{ - ClientInformation, ServerboundClientInformationPacket, +use azalea_protocol::{ + common::client_information::ClientInformation, + packets::config::{ + s_client_information::ServerboundClientInformation, + s_custom_payload::ServerboundCustomPayload, }, - serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, }; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use crate::{ - client::InConfigurationState, packet_handling::configuration::SendConfigurationPacketEvent, -}; +use crate::{client::InConfigurationState, packet_handling::configuration::SendConfigurationEvent}; pub struct ConfigurationPlugin; impl Plugin for ConfigurationPlugin { @@ -26,27 +25,25 @@ impl Plugin for ConfigurationPlugin { fn handle_in_configuration_state( query: Query<(Entity, &ClientInformation), Added>, - mut send_packet_events: EventWriter, + mut send_packet_events: EventWriter, ) { for (entity, client_information) in query.iter() { let mut brand_data = Vec::new(); // they don't have to know :) - "vanilla".write_into(&mut brand_data).unwrap(); - send_packet_events.send(SendConfigurationPacketEvent { + "vanilla".azalea_write(&mut brand_data).unwrap(); + send_packet_events.send(SendConfigurationEvent::new( entity, - packet: ServerboundCustomPayloadPacket { + ServerboundCustomPayload { identifier: ResourceLocation::new("brand"), data: brand_data.into(), - } - .get(), - }); + }, + )); - send_packet_events.send(SendConfigurationPacketEvent { + send_packet_events.send(SendConfigurationEvent::new( entity, - packet: ServerboundClientInformationPacket { + ServerboundClientInformation { information: client_information.clone(), - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/events.rs b/azalea-client/src/events.rs index 61104a4b..fb8afa75 100644 --- a/azalea-client/src/events.rs +++ b/azalea-client/src/events.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use azalea_chat::FormattedText; use azalea_core::tick::GameTick; use azalea_protocol::packets::game::{ - clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, ClientboundGamePacket, + c_player_combat_kill::ClientboundPlayerCombatKill, ClientboundGamePacket, }; use azalea_world::{InstanceName, MinecraftEntityId}; use bevy_app::{App, Plugin, PreUpdate, Update}; @@ -93,7 +93,7 @@ pub enum Event { /// name, or latency changed). UpdatePlayer(PlayerInfo), /// The client player died in-game. - Death(Option>), + Death(Option>), /// A `KeepAlive` packet was sent by the server. KeepAlive(u64), /// The client disconnected from the server. diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs index 94b60ddc..d2dfd93a 100644 --- a/azalea-client/src/interact.rs +++ b/azalea-client/src/interact.rs @@ -10,12 +10,12 @@ use azalea_core::{ use azalea_entity::{ clamp_look_direction, view_vector, Attributes, EyeHeight, LocalEntity, LookDirection, Position, }; -use azalea_inventory::{ItemSlot, ItemSlotData}; +use azalea_inventory::{ItemStack, ItemStackData}; use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType}; use azalea_protocol::packets::game::{ - serverbound_interact_packet::InteractionHand, - serverbound_swing_packet::ServerboundSwingPacket, - serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket}, + s_interact::InteractionHand, + s_swing::ServerboundSwing, + s_use_item_on::{BlockHit, ServerboundUseItemOn}, }; use azalea_registry::DataComponentKind; use azalea_world::{Instance, InstanceContainer, InstanceName}; @@ -148,15 +148,14 @@ pub fn handle_block_interact_event( } }; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundUseItemOnPacket { + ServerboundUseItemOn { hand: InteractionHand::MainHand, block_hit, sequence: sequence_number.0, - } - .get(), - }); + }, + )); } } @@ -245,7 +244,7 @@ pub fn check_is_interaction_restricted( // way of modifying that let held_item = inventory.held_item(); - if let ItemSlot::Present(item) = &held_item { + if let ItemStack::Present(item) = &held_item { let block = instance.chunks.get_block_state(block_pos); let Some(block) = block else { // block isn't loaded so just say that it is restricted @@ -263,7 +262,7 @@ pub fn check_is_interaction_restricted( /// Check if the item has the `CanDestroy` tag for the block. pub fn check_block_can_be_broken_by_item_in_adventure_mode( - item: &ItemSlotData, + item: &ItemStackData, _block: &BlockState, ) -> bool { // minecraft caches the last checked block but that's kind of an unnecessary @@ -302,13 +301,12 @@ pub fn handle_swing_arm_event( mut send_packet_events: EventWriter, ) { for event in events.read() { - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundSwingPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundSwing { hand: InteractionHand::MainHand, - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/inventory.rs b/azalea-client/src/inventory.rs index d4ccab14..eb0b0675 100644 --- a/azalea-client/src/inventory.rs +++ b/azalea-client/src/inventory.rs @@ -10,9 +10,8 @@ use azalea_inventory::{ }, }; use azalea_protocol::packets::game::{ - serverbound_container_click_packet::ServerboundContainerClickPacket, - serverbound_container_close_packet::ServerboundContainerClosePacket, - serverbound_set_carried_item_packet::ServerboundSetCarriedItemPacket, + s_container_click::ServerboundContainerClick, s_container_close::ServerboundContainerClose, + s_set_carried_item::ServerboundSetCarriedItem, }; use azalea_registry::MenuKind; use bevy_app::{App, Plugin, Update}; @@ -98,7 +97,7 @@ pub struct Inventory { /// /// This is different from [`Self::selected_hotbar_slot`], which is the /// item that's selected in the hotbar. - pub carried: ItemSlot, + pub carried: ItemStack, /// An identifier used by the server to track client inventory desyncs. This /// is sent on every container click, and it's only ever updated when the /// server sends a new container update. @@ -183,7 +182,7 @@ impl Inventory { if let QuickCraftStatus::Add { slot } = quick_craft.status { let slot_item = self.menu().slot(slot as usize); if let Some(slot_item) = slot_item { - if let ItemSlot::Present(carried) = &self.carried { + if let ItemStack::Present(carried) = &self.carried { // minecraft also checks slot.may_place(carried) and // menu.can_drag_to(slot) // but they always return true so they're not relevant for us @@ -222,7 +221,7 @@ impl Inventory { return; } - let ItemSlot::Present(mut carried) = self.carried.clone() else { + let ItemStack::Present(mut carried) = self.carried.clone() else { // this should never happen return self.reset_quick_craft(); }; @@ -231,14 +230,14 @@ impl Inventory { let mut quick_craft_slots_iter = self.quick_craft_slots.iter(); loop { - let mut slot: &ItemSlot; + let mut slot: &ItemStack; let mut slot_index: u16; - let mut item_stack: &ItemSlot; + let mut item_stack: &ItemStack; loop { let Some(&next_slot) = quick_craft_slots_iter.next() else { carried.count = carried_count; - self.carried = ItemSlot::Present(carried); + self.carried = ItemStack::Present(carried); return self.reset_quick_craft(); }; @@ -259,8 +258,8 @@ impl Inventory { } } - // get the ItemSlotData for the slot - let ItemSlot::Present(slot) = slot else { + // get the ItemStackData for the slot + let ItemStack::Present(slot) = slot else { unreachable!("the loop above requires the slot to be present to break") }; @@ -293,7 +292,7 @@ impl Inventory { &mut self.inventory_menu }; *menu.slot_mut(slot_index as usize).unwrap() = - ItemSlot::Present(new_carried); + ItemStack::Present(new_carried); } } } else { @@ -316,7 +315,7 @@ impl Inventory { // implementation // player.drop(self.carried, true); - self.carried = ItemSlot::Empty; + self.carried = ItemStack::Empty; } } ClickOperation::Pickup(PickupClick::Right { slot: None }) => { @@ -336,8 +335,8 @@ impl Inventory { // here // i don't understand it so i didn't implement it match slot_item { - ItemSlot::Empty => if carried.is_present() {}, - ItemSlot::Present(_) => todo!(), + ItemStack::Empty => if carried.is_present() {}, + ItemStack::Present(_) => todo!(), } } ClickOperation::QuickMove( @@ -374,7 +373,7 @@ impl Inventory { *target_slot = source_slot; } } else if source_slot.is_empty() { - let ItemSlot::Present(target_item) = target_slot else { + let ItemStack::Present(target_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; if self.menu().may_place(source_slot_index, target_item) { @@ -386,7 +385,7 @@ impl Inventory { *self.menu_mut().slot_mut(source_slot_index).unwrap() = new_source_slot; } } else if self.menu().may_pickup(source_slot_index) { - let ItemSlot::Present(target_item) = target_slot else { + let ItemStack::Present(target_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; if self.menu().may_place(source_slot_index, target_item) { @@ -421,12 +420,12 @@ impl Inventory { let Some(source_slot) = self.menu().slot(*slot as usize) else { return; }; - let ItemSlot::Present(source_item) = source_slot else { + let ItemStack::Present(source_item) = source_slot else { return; }; let mut new_carried = source_item.clone(); new_carried.count = new_carried.kind.max_stack_size(); - self.carried = ItemSlot::Present(new_carried); + self.carried = ItemStack::Present(new_carried); } ClickOperation::Throw(c) => { if self.carried.is_present() { @@ -440,7 +439,7 @@ impl Inventory { let Some(slot) = self.menu_mut().slot_mut(slot_index) else { return; }; - let ItemSlot::Present(slot_item) = slot else { + let ItemStack::Present(slot_item) = slot else { return; }; @@ -467,7 +466,7 @@ impl Inventory { return; } - let ItemSlot::Present(target_slot_item) = &target_slot else { + let ItemStack::Present(target_slot_item) = &target_slot else { unreachable!("target slot is not empty but is not present"); }; @@ -481,7 +480,7 @@ impl Inventory { for i in iterator { if target_slot_item.count < target_slot_item.kind.max_stack_size() { let checking_slot = self.menu().slot(i).unwrap(); - if let ItemSlot::Present(checking_item) = checking_slot { + if let ItemStack::Present(checking_item) = checking_slot { if can_item_quick_replace(checking_slot, &target_slot, true) && self.menu().may_pickup(i) && (round != 0 @@ -496,7 +495,7 @@ impl Inventory { // now extend the carried item let target_slot = &mut self.carried; - let ItemSlot::Present(target_slot_item) = target_slot else { + let ItemStack::Present(target_slot_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; target_slot_item.count += taken_item.count(); @@ -516,7 +515,7 @@ impl Inventory { } /// Get the item in the player's hotbar that is currently being held. - pub fn held_item(&self) -> ItemSlot { + pub fn held_item(&self) -> ItemStack { let inventory = &self.inventory_menu; let hotbar_items = &inventory.slots()[inventory.hotbar_slots_range()]; hotbar_items[self.selected_hotbar_slot as usize].clone() @@ -524,14 +523,14 @@ impl Inventory { } fn can_item_quick_replace( - target_slot: &ItemSlot, - item: &ItemSlot, + target_slot: &ItemStack, + item: &ItemStack, ignore_item_count: bool, ) -> bool { - let ItemSlot::Present(target_slot) = target_slot else { + let ItemStack::Present(target_slot) = target_slot else { return false; }; - let ItemSlot::Present(item) = item else { + let ItemStack::Present(item) = item else { // i *think* this is what vanilla does // not 100% sure lol probably doesn't matter though return false; @@ -552,7 +551,7 @@ fn can_item_quick_replace( fn get_quick_craft_slot_count( quick_craft_slots: &HashSet, quick_craft_kind: &QuickCraftKind, - item: &mut ItemSlotData, + item: &mut ItemStackData, slot_item_count: i32, ) { item.count = match quick_craft_kind { @@ -570,7 +569,7 @@ impl Default for Inventory { id: 0, container_menu: None, container_menu_title: None, - carried: ItemSlot::Empty, + carried: ItemStack::Empty, state_id: 0, quick_craft_status: QuickCraftStatusKind::Start, quick_craft_kind: QuickCraftKind::Middle, @@ -628,13 +627,12 @@ fn handle_container_close_event( continue; } - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundContainerClosePacket { + ServerboundContainerClose { container_id: inventory.id, - } - .get(), - }); + }, + )); client_side_events.send(ClientSideCloseContainerEvent { entity: event.entity, }); @@ -688,7 +686,7 @@ pub fn handle_container_click_event( // see which slots changed after clicking and put them in the hashmap // the server uses this to check if we desynced - let mut changed_slots: HashMap = HashMap::new(); + let mut changed_slots: HashMap = HashMap::new(); for (slot_index, old_slot) in old_slots.iter().enumerate() { let new_slot = &menu.slots()[slot_index]; if old_slot != new_slot { @@ -696,9 +694,9 @@ pub fn handle_container_click_event( } } - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundContainerClickPacket { + ServerboundContainerClick { container_id: event.window_id, state_id: inventory.state_id, slot_num: event.operation.slot_num().map(|n| n as i16).unwrap_or(-999), @@ -706,9 +704,8 @@ pub fn handle_container_click_event( click_type: event.operation.click_type(), changed_slots, carried_item: inventory.carried.clone(), - } - .get(), - }); + }, + )); } } @@ -717,7 +714,7 @@ pub fn handle_container_click_event( #[derive(Event)] pub struct SetContainerContentEvent { pub entity: Entity, - pub slots: Vec, + pub slots: Vec, pub container_id: u8, } fn handle_set_container_content_event( @@ -764,12 +761,11 @@ fn handle_set_selected_hotbar_slot_event( } inventory.selected_hotbar_slot = event.slot; - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundSetCarriedItemPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundSetCarriedItem { slot: event.slot as u16, - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 82d4f561..3e4a48aa 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -30,7 +30,7 @@ pub mod respawn; pub mod task_pool; pub use account::{Account, AccountOpts}; -pub use azalea_protocol::packets::configuration::serverbound_client_information_packet::ClientInformation; +pub use azalea_protocol::common::client_information::ClientInformation; pub use client::{ start_ecs_runner, Client, DefaultPlugins, JoinError, JoinedClientBundle, StartClientOpts, TickBroadcast, diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs index 3cc77f9d..d2fce3f1 100644 --- a/azalea-client/src/local_player.rs +++ b/azalea-client/src/local_player.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, io, sync::Arc}; use azalea_auth::game_profile::GameProfile; use azalea_core::game_type::GameMode; use azalea_entity::Dead; -use azalea_protocol::packets::game::clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket; +use azalea_protocol::packets::game::c_player_abilities::ClientboundPlayerAbilities; use azalea_world::{Instance, PartialInstance}; use bevy_ecs::{component::Component, prelude::*}; use derive_more::{Deref, DerefMut}; @@ -62,8 +62,8 @@ pub struct PlayerAbilities { /// Used for the fov pub walking_speed: f32, } -impl From<&ClientboundPlayerAbilitiesPacket> for PlayerAbilities { - fn from(packet: &ClientboundPlayerAbilitiesPacket) -> Self { +impl From<&ClientboundPlayerAbilities> for PlayerAbilities { + fn from(packet: &ClientboundPlayerAbilities) -> Self { Self { invulnerable: packet.flags.invulnerable, flying: packet.flags.flying, diff --git a/azalea-client/src/mining.rs b/azalea-client/src/mining.rs index 1c8461c5..bf5a48ca 100644 --- a/azalea-client/src/mining.rs +++ b/azalea-client/src/mining.rs @@ -1,11 +1,9 @@ use azalea_block::{Block, BlockState, FluidState}; use azalea_core::{direction::Direction, game_type::GameMode, position::BlockPos, tick::GameTick}; use azalea_entity::{mining::get_mine_progress, FluidOnEyes, Physics}; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use azalea_physics::PhysicsSet; -use azalea_protocol::packets::game::serverbound_player_action_packet::{ - self, ServerboundPlayerActionPacket, -}; +use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction}; use azalea_world::{InstanceContainer, InstanceName}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -253,17 +251,16 @@ fn handle_start_mining_block_with_direction_event( { if mining.is_some() { // send a packet to stop mining since we just changed target - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::AbortDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::AbortDestroyBlock, pos: current_mining_pos .expect("IsMining is true so MineBlockPos must be present"), direction: event.direction, sequence: 0, - } - .get(), - }); + }, + )); } let target_block_state = instance @@ -326,16 +323,15 @@ fn handle_start_mining_block_with_direction_event( }); } - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StartDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::StartDestroyBlock, pos: event.position, direction: event.direction, sequence: **sequence_number, - } - .get(), - }); + }, + )); } } } @@ -407,9 +403,9 @@ pub struct MineTicks(pub f32); pub struct MineBlockPos(pub Option); /// A component that contains the item we're currently using to mine. If we're -/// not mining anything, it'll be [`ItemSlot::Empty`]. +/// not mining anything, it'll be [`ItemStack::Empty`]. #[derive(Component, Clone, Debug, Default, Deref, DerefMut)] -pub struct MineItem(pub ItemSlot); +pub struct MineItem(pub ItemStack); /// Sent when we completed mining a block. #[derive(Event)] @@ -496,16 +492,15 @@ pub fn handle_stop_mining_block_event( let mine_block_pos = mine_block_pos.expect("IsMining is true so MineBlockPos must be present"); - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::AbortDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::AbortDestroyBlock, pos: mine_block_pos, direction: Direction::Down, sequence: 0, - } - .get(), - }); + }, + )); commands.entity(event.entity).remove::(); **mine_progress = 0.; mine_block_progress_events.send(MineBlockProgressEvent { @@ -570,16 +565,15 @@ pub fn continue_mining_block( position: mining.pos, }); *sequence_number += 1; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StartDestroyBlock, + ServerboundPlayerAction { + action: s_player_action::Action::StartDestroyBlock, pos: mining.pos, direction: mining.dir, sequence: **sequence_number, - } - .get(), - }); + }, + )); swing_arm_events.send(SwingArmEvent { entity }); } else if is_same_mining_target( mining.pos, @@ -616,16 +610,15 @@ pub fn continue_mining_block( entity, position: mining.pos, }); - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StopDestroyBlock, + ServerboundPlayerAction { + action: s_player_action::Action::StopDestroyBlock, pos: mining.pos, direction: mining.dir, sequence: **sequence_number, - } - .get(), - }); + }, + )); **mine_progress = 0.; **mine_ticks = 0.; **mine_delay = 0; diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index 806f8734..3304e27d 100644 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -5,12 +5,15 @@ use azalea_core::tick::GameTick; use azalea_entity::{metadata::Sprinting, Attributes, Jumping}; use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position}; use azalea_physics::{ai_step, PhysicsSet}; -use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket; -use azalea_protocol::packets::game::{ - serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket, - serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, - serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket, - serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket, +use azalea_protocol::packets::game::ServerboundPlayerCommand; +use azalea_protocol::packets::{ + game::{ + s_move_player_pos::ServerboundMovePlayerPos, + s_move_player_pos_rot::ServerboundMovePlayerPosRot, + s_move_player_rot::ServerboundMovePlayerRot, + s_move_player_status_only::ServerboundMovePlayerStatusOnly, + }, + Packet, }; use azalea_world::{MinecraftEntityId, MoveEntityError}; use bevy_app::{App, Plugin, Update}; @@ -188,7 +191,7 @@ pub fn send_position( // } let packet = if sending_position && sending_direction { Some( - ServerboundMovePlayerPosRotPacket { + ServerboundMovePlayerPosRot { x: position.x, y: position.y, z: position.z, @@ -196,33 +199,33 @@ pub fn send_position( y_rot: direction.y_rot, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if sending_position { Some( - ServerboundMovePlayerPosPacket { + ServerboundMovePlayerPos { x: position.x, y: position.y, z: position.z, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if sending_direction { Some( - ServerboundMovePlayerRotPacket { + ServerboundMovePlayerRot { x_rot: direction.x_rot, y_rot: direction.y_rot, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if physics.last_on_ground != physics.on_ground { Some( - ServerboundMovePlayerStatusOnlyPacket { + ServerboundMovePlayerStatusOnly { on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else { None @@ -244,7 +247,10 @@ pub fn send_position( }; if let Some(packet) = packet { - send_packet_events.send(SendPacketEvent { entity, packet }); + send_packet_events.send(SendPacketEvent { + sent_by: entity, + packet, + }); } } } @@ -257,19 +263,18 @@ fn send_sprinting_if_needed( let was_sprinting = physics_state.was_sprinting; if **sprinting != was_sprinting { let sprinting_action = if **sprinting { - azalea_protocol::packets::game::serverbound_player_command_packet::Action::StartSprinting + azalea_protocol::packets::game::s_player_command::Action::StartSprinting } else { - azalea_protocol::packets::game::serverbound_player_command_packet::Action::StopSprinting + azalea_protocol::packets::game::s_player_command::Action::StopSprinting }; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerCommandPacket { + ServerboundPlayerCommand { id: **minecraft_entity_id, action: sprinting_action, data: 0, - } - .get(), - }); + }, + )); physics_state.was_sprinting = **sprinting; } } diff --git a/azalea-client/src/packet_handling/configuration.rs b/azalea-client/src/packet_handling/configuration.rs index de365394..e427e36e 100644 --- a/azalea-client/src/packet_handling/configuration.rs +++ b/azalea-client/src/packet_handling/configuration.rs @@ -1,15 +1,14 @@ use std::io::Cursor; use azalea_entity::indexing::EntityIdIndex; -use azalea_protocol::packets::configuration::serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket; -use azalea_protocol::packets::configuration::serverbound_keep_alive_packet::ServerboundKeepAlivePacket; -use azalea_protocol::packets::configuration::serverbound_pong_packet::ServerboundPongPacket; -use azalea_protocol::packets::configuration::serverbound_resource_pack_packet::ServerboundResourcePackPacket; -use azalea_protocol::packets::configuration::serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket; -use azalea_protocol::packets::configuration::{ - ClientboundConfigurationPacket, ServerboundConfigurationPacket, +use azalea_protocol::packets::config::s_finish_configuration::ServerboundFinishConfiguration; +use azalea_protocol::packets::config::s_keep_alive::ServerboundKeepAlive; +use azalea_protocol::packets::config::s_select_known_packs::ServerboundSelectKnownPacks; +use azalea_protocol::packets::config::{ + self, ClientboundConfigPacket, ServerboundConfigPacket, ServerboundCookieResponse, + ServerboundResourcePack, }; -use azalea_protocol::packets::ConnectionProtocol; +use azalea_protocol::packets::{ConnectionProtocol, Packet}; use azalea_protocol::read::deserialize_packet; use bevy_ecs::prelude::*; use bevy_ecs::system::SystemState; @@ -23,29 +22,29 @@ use crate::raw_connection::RawConnection; use crate::InstanceHolder; #[derive(Event, Debug, Clone)] -pub struct ConfigurationPacketEvent { +pub struct ConfigurationEvent { /// The client entity that received the packet. pub entity: Entity, /// The packet that was actually received. - pub packet: ClientboundConfigurationPacket, + pub packet: ClientboundConfigPacket, } pub fn send_packet_events( query: Query<(Entity, &RawConnection), With>, - mut packet_events: ResMut>, + mut packet_events: ResMut>, ) { // we manually clear and send the events at the beginning of each update // since otherwise it'd cause issues with events in process_packet_events // running twice packet_events.clear(); - for (player_entity, raw_connection) in &query { - let packets_lock = raw_connection.incoming_packet_queue(); + for (player_entity, raw_conn) in &query { + let packets_lock = raw_conn.incoming_packet_queue(); let mut packets = packets_lock.lock(); if !packets.is_empty() { for raw_packet in packets.iter() { - let packet = match deserialize_packet::( - &mut Cursor::new(raw_packet), - ) { + let packet = match deserialize_packet::(&mut Cursor::new( + raw_packet, + )) { Ok(packet) => packet, Err(err) => { error!("failed to read packet: {:?}", err); @@ -53,7 +52,7 @@ pub fn send_packet_events( continue; } }; - packet_events.send(ConfigurationPacketEvent { + packet_events.send(ConfigurationEvent { entity: player_entity, packet, }); @@ -66,10 +65,9 @@ pub fn send_packet_events( pub fn process_packet_events(ecs: &mut World) { let mut events_owned = Vec::new(); - let mut system_state: SystemState> = - SystemState::new(ecs); + let mut system_state: SystemState> = SystemState::new(ecs); let mut events = system_state.get_mut(ecs); - for ConfigurationPacketEvent { + for ConfigurationEvent { entity: player_entity, packet, } in events.read() @@ -79,7 +77,7 @@ pub fn process_packet_events(ecs: &mut World) { } for (player_entity, packet) in events_owned { match packet { - ClientboundConfigurationPacket::RegistryData(p) => { + ClientboundConfigPacket::RegistryData(p) => { let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); @@ -90,10 +88,10 @@ pub fn process_packet_events(ecs: &mut World) { instance.registries.append(p.registry_id, p.entries); } - ClientboundConfigurationPacket::CustomPayload(p) => { + ClientboundConfigPacket::CustomPayload(p) => { debug!("Got custom payload packet {p:?}"); } - ClientboundConfigurationPacket::Disconnect(p) => { + ClientboundConfigPacket::Disconnect(p) => { warn!("Got disconnect packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); @@ -103,20 +101,20 @@ pub fn process_packet_events(ecs: &mut World) { reason: Some(p.reason.clone()), }); } - ClientboundConfigurationPacket::FinishConfiguration(p) => { + ClientboundConfigPacket::FinishConfiguration(p) => { debug!("got FinishConfiguration packet: {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let mut raw_connection = query.get_mut(player_entity).unwrap(); + let mut raw_conn = query.get_mut(player_entity).unwrap(); - raw_connection - .write_packet(ServerboundFinishConfigurationPacket {}.get()) + raw_conn + .write_packet(ServerboundFinishConfiguration {}) .expect( "we should be in the right state and encoding this packet shouldn't fail", ); - raw_connection.set_state(ConnectionProtocol::Game); + raw_conn.set_state(ConnectionProtocol::Game); // these components are added now that we're going to be in the Game state ecs.entity_mut(player_entity) @@ -140,7 +138,7 @@ pub fn process_packet_events(ecs: &mut World) { _local_entity: azalea_entity::LocalEntity, }); } - ClientboundConfigurationPacket::KeepAlive(p) => { + ClientboundConfigPacket::KeepAlive(p) => { debug!("Got keep alive packet (in configuration) {p:?} for {player_entity:?}"); let mut system_state: SystemState<( @@ -148,80 +146,91 @@ pub fn process_packet_events(ecs: &mut World) { EventWriter, )> = SystemState::new(ecs); let (query, mut keepalive_events) = system_state.get_mut(ecs); - let raw_connection = query.get(player_entity).unwrap(); + let raw_conn = query.get(player_entity).unwrap(); keepalive_events.send(KeepAliveEvent { entity: player_entity, id: p.id, }); - raw_connection - .write_packet(ServerboundKeepAlivePacket { id: p.id }.get()) + raw_conn + .write_packet(ServerboundKeepAlive { id: p.id }) .unwrap(); } - ClientboundConfigurationPacket::Ping(p) => { + ClientboundConfigPacket::Ping(p) => { debug!("Got ping packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); - raw_connection - .write_packet(ServerboundPongPacket { id: p.id }.get()) + raw_conn + .write_packet(config::s_pong::ServerboundPong { id: p.id }) .unwrap(); } - ClientboundConfigurationPacket::ResourcePackPush(p) => { + ClientboundConfigPacket::ResourcePackPush(p) => { debug!("Got resource pack packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); // always accept resource pack - raw_connection.write_packet( - ServerboundResourcePackPacket { + raw_conn + .write_packet(ServerboundResourcePack { id: p.id, - action: azalea_protocol::packets::configuration::serverbound_resource_pack_packet::Action::Accepted - }.get() - ).unwrap(); + action: config::s_resource_pack::Action::Accepted, + }) + .unwrap(); } - ClientboundConfigurationPacket::ResourcePackPop(_) => { + ClientboundConfigPacket::ResourcePackPop(_) => { // we can ignore this } - ClientboundConfigurationPacket::UpdateEnabledFeatures(p) => { + ClientboundConfigPacket::UpdateEnabledFeatures(p) => { debug!("Got update enabled features packet {p:?}"); } - ClientboundConfigurationPacket::UpdateTags(_p) => { + ClientboundConfigPacket::UpdateTags(_p) => { debug!("Got update tags packet"); } - ClientboundConfigurationPacket::CookieRequest(p) => { + ClientboundConfigPacket::CookieRequest(p) => { debug!("Got cookie request packet {p:?}"); + + let mut system_state: SystemState> = SystemState::new(ecs); + let mut query = system_state.get_mut(ecs); + let raw_conn = query.get_mut(player_entity).unwrap(); + + raw_conn + .write_packet(ServerboundCookieResponse { + key: p.key, + // cookies aren't implemented + payload: None, + }) + .unwrap(); } - ClientboundConfigurationPacket::ResetChat(p) => { + ClientboundConfigPacket::ResetChat(p) => { debug!("Got reset chat packet {p:?}"); } - ClientboundConfigurationPacket::StoreCookie(p) => { + ClientboundConfigPacket::StoreCookie(p) => { debug!("Got store cookie packet {p:?}"); } - ClientboundConfigurationPacket::Transfer(p) => { + ClientboundConfigPacket::Transfer(p) => { debug!("Got transfer packet {p:?}"); } - ClientboundConfigurationPacket::SelectKnownPacks(p) => { + ClientboundConfigPacket::SelectKnownPacks(p) => { debug!("Got select known packs packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); // resource pack management isn't implemented - raw_connection - .write_packet( - ServerboundSelectKnownPacksPacket { - known_packs: vec![], - } - .get(), - ) + raw_conn + .write_packet(ServerboundSelectKnownPacks { + known_packs: vec![], + }) .unwrap(); } + ClientboundConfigPacket::ServerLinks(_) => {} + ClientboundConfigPacket::CustomReportDetails(_) => {} } } } @@ -229,19 +238,25 @@ pub fn process_packet_events(ecs: &mut World) { /// An event for sending a packet to the server while we're in the /// `configuration` state. #[derive(Event)] -pub struct SendConfigurationPacketEvent { - pub entity: Entity, - pub packet: ServerboundConfigurationPacket, +pub struct SendConfigurationEvent { + pub sent_by: Entity, + pub packet: ServerboundConfigPacket, +} +impl SendConfigurationEvent { + pub fn new(sent_by: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { sent_by, packet } + } } pub fn handle_send_packet_event( - mut send_packet_events: EventReader, + mut send_packet_events: EventReader, mut query: Query<&mut RawConnection>, ) { for event in send_packet_events.read() { - if let Ok(raw_connection) = query.get_mut(event.entity) { + if let Ok(raw_conn) = query.get_mut(event.sent_by) { // debug!("Sending packet: {:?}", event.packet); - if let Err(e) = raw_connection.write_packet(event.packet.clone()) { + if let Err(e) = raw_conn.write_packet(event.packet.clone()) { error!("Failed to send packet: {e}"); } } diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs index 3c6ad6b5..38178a63 100644 --- a/azalea-client/src/packet_handling/game.rs +++ b/azalea-client/src/packet_handling/game.rs @@ -17,14 +17,15 @@ use azalea_entity::{ Physics, PlayerBundle, Position, RelativeEntityUpdate, }; use azalea_protocol::{ - packets::game::{ - clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, - serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, - serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket, - serverbound_keep_alive_packet::ServerboundKeepAlivePacket, - serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, - serverbound_pong_packet::ServerboundPongPacket, ClientboundGamePacket, - ServerboundGamePacket, + packets::{ + game::{ + c_player_combat_kill::ClientboundPlayerCombatKill, + s_accept_teleportation::ServerboundAcceptTeleportation, + s_configuration_acknowledged::ServerboundConfigurationAcknowledged, + s_keep_alive::ServerboundKeepAlive, s_move_player_pos_rot::ServerboundMovePlayerPosRot, + s_pong::ServerboundPong, ClientboundGamePacket, ServerboundGamePacket, + }, + Packet, }, read::deserialize_packet, }; @@ -103,12 +104,12 @@ pub struct UpdatePlayerEvent { } /// Event for when an entity dies. dies. If it's a local player and there's a -/// reason in the death screen, the [`ClientboundPlayerCombatKillPacket`] will +/// reason in the death screen, the [`ClientboundPlayerCombatKill`] will /// be included. #[derive(Event, Debug, Clone)] pub struct DeathEvent { pub entity: Entity, - pub packet: Option, + pub packet: Option, } /// A KeepAlive packet is sent from the server to verify that the client is @@ -340,10 +341,9 @@ pub fn process_packet_events(ecs: &mut World) { "Sending client information because login: {:?}", client_information ); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: azalea_protocol::packets::game::serverbound_client_information_packet::ServerboundClientInformationPacket { information: client_information.clone() }.get(), - }); + send_packet_events.send(SendPacketEvent::new(player_entity, + azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() }, + )); system_state.apply(ecs); } @@ -493,13 +493,13 @@ pub fn process_packet_events(ecs: &mut World) { **position = new_pos; } - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundAcceptTeleportationPacket { id: p.id }.get(), - }); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundMovePlayerPosRotPacket { + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundAcceptTeleportation { id: p.id }, + )); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundMovePlayerPosRot { x: new_pos.x, y: new_pos.y, z: new_pos.z, @@ -507,9 +507,8 @@ pub fn process_packet_events(ecs: &mut World) { x_rot, // this is always false on_ground: false, - } - .get(), - }); + }, + )); } ClientboundGamePacket::PlayerInfoUpdate(p) => { debug!("Got player info packet {p:?}"); @@ -983,10 +982,10 @@ pub fn process_packet_events(ecs: &mut World) { entity: player_entity, id: p.id, }); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundKeepAlivePacket { id: p.id }.get(), - }); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundKeepAlive { id: p.id }, + )); } ClientboundGamePacket::RemoveEntities(p) => { debug!("Got remove entities packet {:?}", p); @@ -1096,7 +1095,7 @@ pub fn process_packet_events(ecs: &mut World) { } } ClientboundGamePacket::GameEvent(p) => { - use azalea_protocol::packets::game::clientbound_game_event_packet::EventType; + use azalea_protocol::packets::game::c_game_event::EventType; debug!("Got game event packet {p:?}"); @@ -1279,10 +1278,10 @@ pub fn process_packet_events(ecs: &mut World) { SystemState::new(ecs); let mut send_packet_events = system_state.get_mut(ecs); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundPongPacket { id: p.id }.get(), - }); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundPong { id: p.id }, + )); } ClientboundGamePacket::PlaceGhostRecipe(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {} @@ -1423,10 +1422,10 @@ pub fn process_packet_events(ecs: &mut World) { SystemState::new(ecs); let (mut commands, mut packet_events) = system_state.get_mut(ecs); - packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundConfigurationAcknowledgedPacket {}.get(), - }); + packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundConfigurationAcknowledged {}, + )); commands .entity(player_entity) @@ -1459,7 +1458,7 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::TabList(_) => {} ClientboundGamePacket::TagQuery(_) => {} ClientboundGamePacket::TakeItemEntity(_) => {} - ClientboundGamePacket::Bundle(_) => {} + ClientboundGamePacket::BundleDelimiter(_) => {} ClientboundGamePacket::DamageEvent(_) => {} ClientboundGamePacket::HurtAnimation(_) => {} @@ -1472,7 +1471,7 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::PongResponse(_) => {} ClientboundGamePacket::StoreCookie(_) => {} ClientboundGamePacket::Transfer(_) => {} - ClientboundGamePacket::MoveMinecart(_) => {} + ClientboundGamePacket::MoveMinecartAlongTrack(_) => {} ClientboundGamePacket::SetHeldSlot(_) => {} ClientboundGamePacket::SetPlayerInventory(_) => {} ClientboundGamePacket::ProjectilePower(_) => {} @@ -1490,16 +1489,22 @@ pub fn process_packet_events(ecs: &mut World) { /// An event for sending a packet to the server while we're in the `game` state. #[derive(Event)] pub struct SendPacketEvent { - pub entity: Entity, + pub sent_by: Entity, pub packet: ServerboundGamePacket, } +impl SendPacketEvent { + pub fn new(sent_by: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { sent_by, packet } + } +} pub fn handle_send_packet_event( mut send_packet_events: EventReader, mut query: Query<&mut RawConnection>, ) { for event in send_packet_events.read() { - if let Ok(raw_connection) = query.get_mut(event.entity) { + if let Ok(raw_connection) = query.get_mut(event.sent_by) { // debug!("Sending packet: {:?}", event.packet); if let Err(e) = raw_connection.write_packet(event.packet.clone()) { error!("Failed to send packet: {e}"); diff --git a/azalea-client/src/packet_handling/login.rs b/azalea-client/src/packet_handling/login.rs index 7d71b440..11c0b8e9 100644 --- a/azalea-client/src/packet_handling/login.rs +++ b/azalea-client/src/packet_handling/login.rs @@ -3,9 +3,12 @@ use std::{collections::HashSet, sync::Arc}; -use azalea_protocol::packets::login::{ - serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket, - ClientboundLoginPacket, ServerboundLoginPacket, +use azalea_protocol::packets::{ + login::{ + s_custom_query_answer::ServerboundCustomQueryAnswer, ClientboundLoginPacket, + ServerboundLoginPacket, + }, + Packet, }; use bevy_ecs::{prelude::*, system::SystemState}; use derive_more::{Deref, DerefMut}; @@ -33,6 +36,12 @@ pub struct SendLoginPacketEvent { pub entity: Entity, pub packet: ServerboundLoginPacket, } +impl SendLoginPacketEvent { + pub fn new(entity: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { entity, packet } + } +} #[derive(Component)] pub struct LoginSendPacketQueue { @@ -86,14 +95,13 @@ pub fn process_packet_events(ecs: &mut World) { } } - send_packet_events.send(SendLoginPacketEvent { - entity: player_entity, - packet: ServerboundCustomQueryAnswerPacket { + send_packet_events.send(SendLoginPacketEvent::new( + player_entity, + ServerboundCustomQueryAnswer { transaction_id: p.transaction_id, data: None, - } - .get(), - }); + }, + )); } _ => {} } diff --git a/azalea-client/src/packet_handling/mod.rs b/azalea-client/src/packet_handling/mod.rs index eb8f1d47..6bb9c319 100644 --- a/azalea-client/src/packet_handling/mod.rs +++ b/azalea-client/src/packet_handling/mod.rs @@ -61,9 +61,9 @@ impl Plugin for PacketHandlerPlugin { ) // we do this instead of add_event so we can handle the events ourselves .init_resource::>() - .init_resource::>() + .init_resource::>() .add_event::() - .add_event::() + .add_event::() .add_event::() .add_event::() .add_event::() diff --git a/azalea-client/src/ping.rs b/azalea-client/src/ping.rs index ded1b521..f5d714cd 100755 --- a/azalea-client/src/ping.rs +++ b/azalea-client/src/ping.rs @@ -5,14 +5,13 @@ use std::io; use azalea_protocol::{ connect::{Connection, ConnectionError, Proxy}, packets::{ - handshaking::{ - client_intention_packet::ClientIntentionPacket, ClientboundHandshakePacket, + handshake::{ + s_intention::ServerboundIntention, ClientboundHandshakePacket, ServerboundHandshakePacket, }, status::{ - clientbound_status_response_packet::ClientboundStatusResponsePacket, - serverbound_status_request_packet::ServerboundStatusRequestPacket, - ClientboundStatusPacket, + c_status_response::ClientboundStatusResponse, + s_status_request::ServerboundStatusRequest, ClientboundStatusPacket, }, ClientIntention, PROTOCOL_VERSION, }, @@ -49,7 +48,7 @@ pub enum PingError { /// ``` pub async fn ping_server( address: impl TryInto, -) -> Result { +) -> Result { let address: ServerAddress = address.try_into().map_err(|_| PingError::InvalidAddress)?; let resolved_address = resolver::resolve_address(&address).await?; let conn = Connection::new(&resolved_address).await?; @@ -60,7 +59,7 @@ pub async fn ping_server( pub async fn ping_server_with_proxy( address: impl TryInto, proxy: Proxy, -) -> Result { +) -> Result { let address: ServerAddress = address.try_into().map_err(|_| PingError::InvalidAddress)?; let resolved_address = resolver::resolve_address(&address).await?; let conn = Connection::new_with_proxy(&resolved_address, proxy).await?; @@ -73,22 +72,19 @@ pub async fn ping_server_with_proxy( pub async fn ping_server_with_connection( address: ServerAddress, mut conn: Connection, -) -> Result { +) -> Result { // send the client intention packet and switch to the status state - conn.write( - ClientIntentionPacket { - protocol_version: PROTOCOL_VERSION, - hostname: address.host.clone(), - port: address.port, - intention: ClientIntention::Status, - } - .get(), - ) + conn.write(ServerboundIntention { + protocol_version: PROTOCOL_VERSION, + hostname: address.host.clone(), + port: address.port, + intention: ClientIntention::Status, + }) .await?; let mut conn = conn.status(); // send the empty status request packet - conn.write(ServerboundStatusRequestPacket {}.get()).await?; + conn.write(ServerboundStatusRequest {}).await?; let packet = conn.read().await?; diff --git a/azalea-client/src/raw_connection.rs b/azalea-client/src/raw_connection.rs index 8cbb15a4..3eacf528 100644 --- a/azalea-client/src/raw_connection.rs +++ b/azalea-client/src/raw_connection.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use azalea_protocol::{ connect::{RawReadConnection, RawWriteConnection}, - packets::{ConnectionProtocol, ProtocolPacket}, + packets::{ConnectionProtocol, Packet, ProtocolPacket}, read::ReadPacketError, write::serialize_packet, }; @@ -106,8 +106,9 @@ impl RawConnection { /// encoding it failed somehow (like it's too big or something). pub fn write_packet( &self, - packet: P, + packet: impl Packet

, ) -> Result<(), WritePacketError> { + let packet = packet.into_variant(); let raw_packet = serialize_packet(&packet)?; self.write_raw_packet(raw_packet)?; diff --git a/azalea-client/src/respawn.rs b/azalea-client/src/respawn.rs index 150b3591..edd2a43a 100644 --- a/azalea-client/src/respawn.rs +++ b/azalea-client/src/respawn.rs @@ -1,6 +1,4 @@ -use azalea_protocol::packets::game::serverbound_client_command_packet::{ - self, ServerboundClientCommandPacket, -}; +use azalea_protocol::packets::game::s_client_command::{self, ServerboundClientCommand}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -26,12 +24,11 @@ pub fn perform_respawn( mut send_packets: EventWriter, ) { for event in events.read() { - send_packets.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundClientCommandPacket { - action: serverbound_client_command_packet::Action::PerformRespawn, - } - .get(), - }); + send_packets.send(SendPacketEvent::new( + event.entity, + ServerboundClientCommand { + action: s_client_command::Action::PerformRespawn, + }, + )); } } diff --git a/azalea-core/Cargo.toml b/azalea-core/Cargo.toml index bc65399f..ddde6216 100644 --- a/azalea-core/Cargo.toml +++ b/azalea-core/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-core" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-core" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-core/src/bitset.rs b/azalea-core/src/bitset.rs index 0be04a57..e7c79467 100755 --- a/azalea-core/src/bitset.rs +++ b/azalea-core/src/bitset.rs @@ -1,9 +1,9 @@ use std::io::{Cursor, Write}; -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; /// Represents Java's BitSet, a list of bits. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, McBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, AzBuf)] pub struct BitSet { data: Vec, } @@ -159,25 +159,25 @@ where } } -impl McBufReadable for FixedBitSet +impl AzaleaRead for FixedBitSet where [u8; N.div_ceil(8)]: Sized, { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { let mut data = [0; N.div_ceil(8)]; for item in data.iter_mut().take(N.div_ceil(8)) { - *item = u8::read_from(buf)?; + *item = u8::azalea_read(buf)?; } Ok(FixedBitSet { data }) } } -impl McBufWritable for FixedBitSet +impl AzaleaWrite for FixedBitSet where [u8; N.div_ceil(8)]: Sized, { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for i in 0..N.div_ceil(8) { - self.data[i].write_into(buf)?; + self.data[i].azalea_write(buf)?; } Ok(()) } diff --git a/azalea-core/src/delta.rs b/azalea-core/src/delta.rs index 2dd67005..238262a2 100755 --- a/azalea-core/src/delta.rs +++ b/azalea-core/src/delta.rs @@ -1,4 +1,4 @@ -pub use azalea_buf::McBuf; +pub use azalea_buf::AzBuf; use crate::position::Vec3; @@ -9,7 +9,7 @@ pub trait PositionDeltaTrait { } /// Only works for up to 8 blocks -#[derive(Clone, Debug, McBuf, Default)] +#[derive(Clone, Debug, AzBuf, Default)] pub struct PositionDelta8 { pub xa: i16, pub ya: i16, @@ -49,10 +49,6 @@ impl Vec3 { } } - pub fn length_squared(&self) -> f64 { - self.x * self.x + self.y * self.y + self.z * self.z - } - pub fn normalize(&self) -> Vec3 { let length = f64::sqrt(self.x * self.x + self.y * self.y + self.z * self.z); if length < 1e-4 { diff --git a/azalea-core/src/difficulty.rs b/azalea-core/src/difficulty.rs index 750cfe1f..b907bbb3 100755 --- a/azalea-core/src/difficulty.rs +++ b/azalea-core/src/difficulty.rs @@ -3,7 +3,7 @@ use std::{ io::{Cursor, Write}, }; -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; #[derive(Hash, Clone, Copy, Debug, PartialEq, Eq)] pub enum Difficulty { @@ -66,15 +66,15 @@ impl Difficulty { } } -impl McBufReadable for Difficulty { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(Difficulty::by_id(u8::read_from(buf)?)) +impl AzaleaRead for Difficulty { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + Ok(Difficulty::by_id(u8::azalea_read(buf)?)) } } -impl McBufWritable for Difficulty { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u8::write_into(&self.id(), buf) +impl AzaleaWrite for Difficulty { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u8::azalea_write(&self.id(), buf) } } diff --git a/azalea-core/src/direction.rs b/azalea-core/src/direction.rs index 32e1a23a..b0b8c960 100755 --- a/azalea-core/src/direction.rs +++ b/azalea-core/src/direction.rs @@ -1,8 +1,8 @@ -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use crate::position::Vec3; -#[derive(Clone, Copy, Debug, McBuf, Default, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, AzBuf, Default, Eq, PartialEq)] pub enum Direction { #[default] Down = 0, @@ -62,7 +62,7 @@ impl Direction { } // TODO: make azalea_block use this instead of FacingCardinal -#[derive(Clone, Copy, Debug, McBuf, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, AzBuf, PartialEq, Eq, Hash)] pub enum CardinalDirection { North, South, diff --git a/azalea-core/src/game_type.rs b/azalea-core/src/game_type.rs index 1e494035..5bac06d5 100644 --- a/azalea-core/src/game_type.rs +++ b/azalea-core/src/game_type.rs @@ -1,6 +1,6 @@ use std::io::{Cursor, Write}; -use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, BufReadError}; use tracing::debug; /// A Minecraft gamemode, like survival or creative. @@ -93,9 +93,9 @@ impl GameMode { } } -impl McBufReadable for GameMode { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let id = u32::var_read_from(buf)?; +impl AzaleaRead for GameMode { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let id = u32::azalea_read_var(buf)?; let id = id.try_into().unwrap_or_else(|_| { debug!("Unknown game mode id {id}, defaulting to survival"); 0 @@ -107,13 +107,13 @@ impl McBufReadable for GameMode { } } -impl McBufWritable for GameMode { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u8::write_into(&self.to_id(), buf) +impl AzaleaWrite for GameMode { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u8::azalea_write(&self.to_id(), buf) } } -/// Rust doesn't let us `impl McBufReadable for Option` so we have to +/// Rust doesn't let us `impl AzaleaRead for Option` so we have to /// make a new type :( #[derive(Hash, Copy, Clone, Debug)] pub struct OptionalGameType(pub Option); @@ -130,15 +130,15 @@ impl From for Option { } } -impl McBufReadable for OptionalGameType { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let id = i8::read_from(buf)?; +impl AzaleaRead for OptionalGameType { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let id = i8::azalea_read(buf)?; GameMode::from_optional_id(id).ok_or(BufReadError::UnexpectedEnumVariant { id: id as i32 }) } } -impl McBufWritable for OptionalGameType { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - GameMode::to_optional_id(*self).write_into(buf) +impl AzaleaWrite for OptionalGameType { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + GameMode::to_optional_id(*self).azalea_write(buf) } } diff --git a/azalea-core/src/objectives.rs b/azalea-core/src/objectives.rs index dd1534f2..a2f0d517 100644 --- a/azalea-core/src/objectives.rs +++ b/azalea-core/src/objectives.rs @@ -3,9 +3,9 @@ use std::{ str::FromStr, }; -use azalea_buf::McBuf; +use azalea_buf::AzBuf; -#[derive(Clone, Copy, Debug, McBuf)] +#[derive(Clone, Copy, Debug, AzBuf)] pub enum ObjectiveCriteria { Integer, Hearts, diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index de0276a3..c280a85a 100755 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -8,11 +8,9 @@ use std::{ hash::Hash, io::{Cursor, Write}, ops::{Add, AddAssign, Mul, Rem, Sub}, - str::FromStr, }; -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; -#[cfg(feature = "serde")] +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; use serde::{Deserialize, Serialize}; use crate::resource_location::ResourceLocation; @@ -28,25 +26,25 @@ macro_rules! vec3_impl { /// Get the distance of this vector to the origin by doing `x^2 + y^2 + /// z^2`. #[inline] - pub fn length_sqr(&self) -> $type { + pub fn length_squared(&self) -> $type { self.x * self.x + self.y * self.y + self.z * self.z } /// Get the squared distance from this position to another position. - /// Equivalent to `(self - other).length_sqr()`. + /// Equivalent to `(self - other).length_squared()`. #[inline] - pub fn distance_to_sqr(&self, other: &Self) -> $type { - (self - other).length_sqr() + pub fn distance_squared_to(&self, other: &Self) -> $type { + (self - other).length_squared() } #[inline] - pub fn horizontal_distance_sqr(&self) -> $type { + pub fn horizontal_distance_squared(&self) -> $type { self.x * self.x + self.z * self.z } #[inline] - pub fn horizontal_distance_to_sqr(&self, other: &Self) -> $type { - (self - other).horizontal_distance_sqr() + pub fn horizontal_distance_squared_to(&self, other: &Self) -> $type { + (self - other).horizontal_distance_squared() } /// Return a new instance of this position with the y coordinate @@ -214,7 +212,7 @@ macro_rules! vec3_impl { /// Used to represent an exact position in the world where an entity could be. /// For blocks, [`BlockPos`] is used instead. -#[derive(Clone, Copy, Debug, Default, PartialEq, McBuf)] +#[derive(Clone, Copy, Debug, Default, PartialEq, AzBuf)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct Vec3 { pub x: f64, @@ -272,6 +270,46 @@ impl BlockPos { pub fn length_manhattan(&self) -> u32 { (self.x.abs() + self.y.abs() + self.z.abs()) as u32 } + + /// Make a new BlockPos with the lower coordinates for each axis. + /// + /// ``` + /// # use azalea_core::position::BlockPos; + /// assert_eq!( + /// BlockPos::min( + /// &BlockPos::new(1, 20, 300), + /// &BlockPos::new(50, 40, 30), + /// ), + /// BlockPos::new(1, 20, 30), + /// ); + /// ``` + pub fn min(&self, other: &Self) -> Self { + Self { + x: self.x.min(other.x), + y: self.y.min(other.y), + z: self.z.min(other.z), + } + } + + /// Make a new BlockPos with the higher coordinates for each axis. + /// + /// ``` + /// # use azalea_core::position::BlockPos; + /// assert_eq!( + /// BlockPos::max( + /// &BlockPos::new(1, 20, 300), + /// &BlockPos::new(50, 40, 30), + /// ), + /// BlockPos::new(50, 40, 300), + /// ); + /// ``` + pub fn max(&self, other: &Self) -> Self { + Self { + x: self.x.max(other.x), + y: self.y.max(other.y), + z: self.z.max(other.z), + } + } } /// Chunk coordinates are used to represent where a chunk is in the world. You @@ -315,15 +353,15 @@ impl From for ChunkPos { } } } -impl McBufReadable for ChunkPos { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let long = u64::read_from(buf)?; +impl AzaleaRead for ChunkPos { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let long = u64::azalea_read(buf)?; Ok(ChunkPos::from(long)) } } -impl McBufWritable for ChunkPos { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - u64::from(*self).write_into(buf)?; +impl AzaleaWrite for ChunkPos { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u64::from(*self).azalea_write(buf)?; Ok(()) } } @@ -586,9 +624,9 @@ const PACKED_Z_MASK: u64 = (1 << PACKED_Z_LENGTH) - 1; const Z_OFFSET: u64 = PACKED_Y_LENGTH; const X_OFFSET: u64 = PACKED_Y_LENGTH + PACKED_Z_LENGTH; -impl McBufReadable for BlockPos { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let val = i64::read_from(buf)?; +impl AzaleaRead for BlockPos { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let val = i64::azalea_read(buf)?; let x = (val << (64 - X_OFFSET - PACKED_X_LENGTH) >> (64 - PACKED_X_LENGTH)) as i32; let y = (val << (64 - PACKED_Y_LENGTH) >> (64 - PACKED_Y_LENGTH)) as i32; let z = (val << (64 - Z_OFFSET - PACKED_Z_LENGTH) >> (64 - PACKED_Z_LENGTH)) as i32; @@ -596,18 +634,18 @@ impl McBufReadable for BlockPos { } } -impl McBufReadable for GlobalPos { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for GlobalPos { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { Ok(GlobalPos { - world: ResourceLocation::read_from(buf)?, - pos: BlockPos::read_from(buf)?, + world: ResourceLocation::azalea_read(buf)?, + pos: BlockPos::azalea_read(buf)?, }) } } -impl McBufReadable for ChunkSectionPos { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let long = i64::read_from(buf)?; +impl AzaleaRead for ChunkSectionPos { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let long = i64::azalea_read(buf)?; Ok(ChunkSectionPos { x: (long >> 42) as i32, y: (long << 44 >> 44) as i32, @@ -616,80 +654,35 @@ impl McBufReadable for ChunkSectionPos { } } -impl McBufWritable for BlockPos { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for BlockPos { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut val: u64 = 0; val |= ((self.x as u64) & PACKED_X_MASK) << X_OFFSET; val |= (self.y as u64) & PACKED_Y_MASK; val |= ((self.z as u64) & PACKED_Z_MASK) << Z_OFFSET; - val.write_into(buf) + val.azalea_write(buf) } } -impl McBufWritable for GlobalPos { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - ResourceLocation::write_into(&self.world, buf)?; - BlockPos::write_into(&self.pos, buf)?; +impl AzaleaWrite for GlobalPos { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + ResourceLocation::azalea_write(&self.world, buf)?; + BlockPos::azalea_write(&self.pos, buf)?; Ok(()) } } -impl McBufWritable for ChunkSectionPos { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for ChunkSectionPos { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let long = (((self.x & 0x3FFFFF) as i64) << 42) | (self.y & 0xFFFFF) as i64 | (((self.z & 0x3FFFFF) as i64) << 20); - long.write_into(buf)?; + long.azalea_write(buf)?; Ok(()) } } -fn parse_three_values(s: &str) -> Result<[T; 3], &'static str> -where - T: FromStr, - ::Err: fmt::Debug, -{ - let parts = s.split_whitespace().collect::>(); - if parts.len() != 3 { - return Err("Expected three values"); - } - - let x = parts[0].parse().map_err(|_| "Invalid X value")?; - let y = parts[1].parse().map_err(|_| "Invalid Y value")?; - let z = parts[2].parse().map_err(|_| "Invalid Z value")?; - - Ok([x, y, z]) -} - -/// Parses a string in the format "X Y Z" into a BlockPos. -/// -/// The input string should contain three integer values separated by spaces, -/// representing the x, y, and z components of the vector respectively. -/// This can be used to parse user input or from `BlockPos::to_string`. -impl FromStr for BlockPos { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - let [x, y, z] = parse_three_values::(s)?; - Ok(BlockPos { x, y, z }) - } -} - -/// Parses a string in the format "X Y Z" into a Vec3. -/// -/// The input string should contain three floating-point values separated by -/// spaces, representing the x, y, and z components of the vector respectively. -/// This can be used to parse user input or from `Vec3::to_string`. -impl FromStr for Vec3 { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - let [x, y, z] = parse_three_values::(s)?; - Ok(Vec3 { x, y, z }) - } -} - #[cfg(test)] mod tests { use super::*; @@ -733,9 +726,9 @@ mod tests { #[test] fn test_read_blockpos_from() { let mut buf = Vec::new(); - 13743895338965u64.write_into(&mut buf).unwrap(); + 13743895338965u64.azalea_write(&mut buf).unwrap(); let mut buf = Cursor::new(&buf[..]); - let block_pos = BlockPos::read_from(&mut buf).unwrap(); + let block_pos = BlockPos::azalea_read(&mut buf).unwrap(); assert_eq!(block_pos, BlockPos::new(49, -43, -3)); } @@ -751,9 +744,9 @@ mod tests { #[test] fn test_read_chunk_pos_from() { let mut buf = Vec::new(); - ChunkPos::new(2, -1).write_into(&mut buf).unwrap(); + ChunkPos::new(2, -1).azalea_write(&mut buf).unwrap(); let mut buf = Cursor::new(&buf[..]); - let chunk_pos = ChunkPos::from(u64::read_from(&mut buf).unwrap()); + let chunk_pos = ChunkPos::from(u64::azalea_read(&mut buf).unwrap()); assert_eq!(chunk_pos, ChunkPos::new(2, -1)); } } diff --git a/azalea-core/src/resource_location.rs b/azalea-core/src/resource_location.rs index 7e1e48fe..c95e3109 100755 --- a/azalea-core/src/resource_location.rs +++ b/azalea-core/src/resource_location.rs @@ -6,7 +6,7 @@ use std::{ str::FromStr, }; -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; #[cfg(feature = "serde")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use simdnbt::{owned::NbtTag, FromNbtTag, ToNbtTag}; @@ -60,15 +60,15 @@ impl FromStr for ResourceLocation { } } -impl McBufReadable for ResourceLocation { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let location_string = String::read_from(buf)?; +impl AzaleaRead for ResourceLocation { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let location_string = String::azalea_read(buf)?; Ok(ResourceLocation::new(&location_string)) } } -impl McBufWritable for ResourceLocation { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.to_string().write_into(buf) +impl AzaleaWrite for ResourceLocation { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.to_string().azalea_write(buf) } } @@ -142,16 +142,16 @@ mod tests { } #[test] - fn mcbuf_resource_location() { + fn azbuf_resource_location() { let mut buf = Vec::new(); ResourceLocation::new("minecraft:dirt") - .write_into(&mut buf) + .azalea_write(&mut buf) .unwrap(); let mut buf = Cursor::new(&buf[..]); assert_eq!( - ResourceLocation::read_from(&mut buf).unwrap(), + ResourceLocation::azalea_read(&mut buf).unwrap(), ResourceLocation::new("minecraft:dirt") ); } diff --git a/azalea-crypto/Cargo.toml b/azalea-crypto/Cargo.toml index 6369377b..a9c6b254 100644 --- a/azalea-crypto/Cargo.toml +++ b/azalea-crypto/Cargo.toml @@ -3,7 +3,7 @@ description = "Cryptography features used in Minecraft." edition = "2021" license = "MIT" name = "azalea-crypto" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-crypto" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-crypto/src/signing.rs b/azalea-crypto/src/signing.rs index 5ecafa46..ba9cc305 100755 --- a/azalea-crypto/src/signing.rs +++ b/azalea-crypto/src/signing.rs @@ -1,6 +1,6 @@ use std::time::{SystemTime, UNIX_EPOCH}; -use azalea_buf::{McBuf, McBufWritable}; +use azalea_buf::{AzBuf, AzaleaWrite}; use rsa::{ signature::{RandomizedSigner, SignatureEncoding}, RsaPrivateKey, @@ -8,18 +8,18 @@ use rsa::{ use sha2::Sha256; use uuid::Uuid; -#[derive(Debug, Clone, McBuf)] +#[derive(Debug, Clone, AzBuf)] pub struct SaltSignaturePair { pub salt: u64, pub signature: Vec, } -#[derive(Clone, Debug, PartialEq, McBuf)] +#[derive(Clone, Debug, PartialEq, AzBuf)] pub struct MessageSignature { pub bytes: [u8; 256], } -#[derive(Clone, Debug, McBuf, PartialEq)] +#[derive(Clone, Debug, AzBuf, PartialEq)] pub struct SignedMessageHeader { pub previous_signature: Option, pub sender: Uuid, @@ -51,17 +51,17 @@ pub struct SignChatMessageOptions { pub fn sign_chat_message(opts: &SignChatMessageOptions) -> MessageSignature { let mut data_to_sign = Vec::new(); // always 1 for some reason - 1i32.write_into(&mut data_to_sign).unwrap(); + 1i32.azalea_write(&mut data_to_sign).unwrap(); // player uuid - opts.account_uuid.write_into(&mut data_to_sign).unwrap(); + opts.account_uuid.azalea_write(&mut data_to_sign).unwrap(); // chat session uuid opts.chat_session_uuid - .write_into(&mut data_to_sign) + .azalea_write(&mut data_to_sign) .unwrap(); // message index - opts.message_index.write_into(&mut data_to_sign).unwrap(); + opts.message_index.azalea_write(&mut data_to_sign).unwrap(); // salt - opts.salt.write_into(&mut data_to_sign).unwrap(); + opts.salt.azalea_write(&mut data_to_sign).unwrap(); // timestamp as seconds let seconds_since_epoch = opts @@ -69,16 +69,16 @@ pub fn sign_chat_message(opts: &SignChatMessageOptions) -> MessageSignature { .duration_since(UNIX_EPOCH) .expect("timestamp must be after epoch") .as_secs(); - seconds_since_epoch.write_into(&mut data_to_sign).unwrap(); + seconds_since_epoch.azalea_write(&mut data_to_sign).unwrap(); // message length as u32 let message_len: u32 = opts.message.len().try_into().unwrap(); - message_len.write_into(&mut data_to_sign).unwrap(); + message_len.azalea_write(&mut data_to_sign).unwrap(); // message bytes data_to_sign.extend_from_slice(opts.message.as_bytes()); // last seen messages length - 0i32.write_into(&mut data_to_sign).unwrap(); + 0i32.azalea_write(&mut data_to_sign).unwrap(); // signatures of last seen messages // ... not implemented yet diff --git a/azalea-entity/Cargo.toml b/azalea-entity/Cargo.toml index 2f294857..14068d20 100644 --- a/azalea-entity/Cargo.toml +++ b/azalea-entity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "azalea-entity" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" edition = "2021" description = "Things related to Minecraft entities used by Azalea" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-entity" @@ -11,7 +11,9 @@ license = "MIT" [dependencies] azalea-block = { version = "0.10.0", path = "../azalea-block" } azalea-buf = { version = "0.10.0", path = "../azalea-buf" } -azalea-chat = { version = "0.10.0", path = "../azalea-chat", features = ["azalea-buf"] } +azalea-chat = { version = "0.10.0", path = "../azalea-chat", features = [ + "azalea-buf", +] } azalea-core = { version = "0.10.0", path = "../azalea-core" } azalea-inventory = { version = "0.10.0", path = "../azalea-inventory" } azalea-registry = { version = "0.10.0", path = "../azalea-registry" } diff --git a/azalea-entity/src/attributes.rs b/azalea-entity/src/attributes.rs index ddafaec3..797ea43c 100644 --- a/azalea-entity/src/attributes.rs +++ b/azalea-entity/src/attributes.rs @@ -2,7 +2,7 @@ use std::collections::{hash_map, HashMap}; -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use azalea_core::resource_location::ResourceLocation; use bevy_ecs::component::Component; use thiserror::Error; @@ -71,14 +71,14 @@ impl AttributeInstance { } } -#[derive(Clone, Debug, McBuf)] +#[derive(Clone, Debug, AzBuf)] pub struct AttributeModifier { pub id: ResourceLocation, pub amount: f64, pub operation: AttributeModifierOperation, } -#[derive(Clone, Debug, Copy, McBuf)] +#[derive(Clone, Debug, Copy, AzBuf)] pub enum AttributeModifierOperation { Addition, MultiplyBase, diff --git a/azalea-entity/src/data.rs b/azalea-entity/src/data.rs index 050302ca..084fd26e 100755 --- a/azalea-entity/src/data.rs +++ b/azalea-entity/src/data.rs @@ -2,15 +2,13 @@ use std::io::{Cursor, Write}; -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use azalea_chat::FormattedText; use azalea_core::{ direction::Direction, position::{BlockPos, GlobalPos, Vec3}, }; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use bevy_ecs::component::Component; use derive_more::Deref; use enum_as_inner::EnumAsInner; @@ -29,35 +27,35 @@ pub struct EntityDataItem { pub value: EntityDataValue, } -impl McBufReadable for EntityMetadataItems { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { +impl AzaleaRead for EntityMetadataItems { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { let mut metadata = Vec::new(); loop { - let id = u8::read_from(buf)?; + let id = u8::azalea_read(buf)?; if id == 0xff { break; } - let value = EntityDataValue::read_from(buf)?; + let value = EntityDataValue::azalea_read(buf)?; metadata.push(EntityDataItem { index: id, value }); } Ok(EntityMetadataItems(metadata)) } } -impl McBufWritable for EntityMetadataItems { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for EntityMetadataItems { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for item in &self.0 { - item.index.write_into(buf)?; - item.value.write_into(buf)?; + item.index.azalea_write(buf)?; + item.value.azalea_write(buf)?; } - 0xffu8.write_into(buf)?; + 0xffu8.azalea_write(buf)?; Ok(()) } } // Note: This enum is partially generated and parsed by // codegen/lib/code/entity.py -#[derive(Clone, Debug, EnumAsInner, McBuf)] +#[derive(Clone, Debug, EnumAsInner, AzBuf)] pub enum EntityDataValue { Byte(u8), Int(#[var] i32), @@ -66,7 +64,7 @@ pub enum EntityDataValue { String(String), FormattedText(FormattedText), OptionalFormattedText(Option), - ItemStack(ItemSlot), + ItemStack(ItemStack), Boolean(bool), Rotations(Rotations), BlockPos(BlockPos), @@ -97,7 +95,7 @@ pub enum EntityDataValue { #[derive(Clone, Debug)] pub struct OptionalUnsignedInt(pub Option); -#[derive(Clone, Debug, McBuf)] +#[derive(Clone, Debug, AzBuf)] pub struct Quaternion { pub x: f32, pub y: f32, @@ -107,7 +105,7 @@ pub struct Quaternion { // mojang just calls this ArmadilloState but i added "Kind" since otherwise it // collides with a name in metadata.rs -#[derive(Clone, Debug, Copy, Default, McBuf)] +#[derive(Clone, Debug, Copy, Default, AzBuf)] pub enum ArmadilloStateKind { #[default] Idle, @@ -115,9 +113,9 @@ pub enum ArmadilloStateKind { Scared, } -impl McBufReadable for OptionalUnsignedInt { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let val = u32::var_read_from(buf)?; +impl AzaleaRead for OptionalUnsignedInt { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let val = u32::azalea_read_var(buf)?; Ok(OptionalUnsignedInt(if val == 0 { None } else { @@ -125,24 +123,24 @@ impl McBufReadable for OptionalUnsignedInt { })) } } -impl McBufWritable for OptionalUnsignedInt { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for OptionalUnsignedInt { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self.0 { - Some(val) => (val + 1).var_write_into(buf), - None => 0u32.var_write_into(buf), + Some(val) => (val + 1).azalea_write_var(buf), + None => 0u32.azalea_write_var(buf), } } } /// A set of x, y, and z rotations. This is used for armor stands. -#[derive(Clone, Debug, McBuf, Default)] +#[derive(Clone, Debug, AzBuf, Default)] pub struct Rotations { pub x: f32, pub y: f32, pub z: f32, } -#[derive(Clone, Debug, Copy, McBuf, Default, Component, Eq, PartialEq)] +#[derive(Clone, Debug, Copy, AzBuf, Default, Component, Eq, PartialEq)] pub enum Pose { #[default] Standing = 0, @@ -155,7 +153,7 @@ pub enum Pose { Dying, } -#[derive(Debug, Clone, McBuf)] +#[derive(Debug, Clone, AzBuf)] pub struct VillagerData { pub kind: azalea_registry::VillagerKind, pub profession: azalea_registry::VillagerProfession, @@ -163,7 +161,7 @@ pub struct VillagerData { pub level: u32, } -#[derive(Debug, Copy, Clone, McBuf, Default)] +#[derive(Debug, Copy, Clone, AzBuf, Default)] pub enum SnifferState { #[default] Idling, diff --git a/azalea-entity/src/metadata.rs b/azalea-entity/src/metadata.rs index 2a6f996e..4054bfb3 100644 --- a/azalea-entity/src/metadata.rs +++ b/azalea-entity/src/metadata.rs @@ -8,7 +8,7 @@ use azalea_core::{ direction::Direction, position::{BlockPos, Vec3}, }; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use bevy_ecs::{bundle::Bundle, component::Component}; use derive_more::{Deref, DerefMut}; use thiserror::Error; @@ -3301,7 +3301,7 @@ impl Default for DrownedMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct EggItemStack(pub ItemSlot); +pub struct EggItemStack(pub ItemStack); #[derive(Component)] pub struct Egg; impl Egg { @@ -3558,7 +3558,7 @@ impl Default for EnderDragonMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct EnderPearlItemStack(pub ItemSlot); +pub struct EnderPearlItemStack(pub ItemStack); #[derive(Component)] pub struct EnderPearl; impl EnderPearl { @@ -3894,7 +3894,7 @@ impl Default for EvokerFangsMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct ExperienceBottleItemStack(pub ItemSlot); +pub struct ExperienceBottleItemStack(pub ItemStack); #[derive(Component)] pub struct ExperienceBottle; impl ExperienceBottle { @@ -3991,7 +3991,7 @@ impl Default for ExperienceOrbMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct EyeOfEnderItemStack(pub ItemSlot); +pub struct EyeOfEnderItemStack(pub ItemStack); #[derive(Component)] pub struct EyeOfEnder; impl EyeOfEnder { @@ -4095,7 +4095,7 @@ impl Default for FallingBlockMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct FireballItemStack(pub ItemSlot); +pub struct FireballItemStack(pub ItemStack); #[derive(Component)] pub struct Fireball; impl Fireball { @@ -4147,7 +4147,7 @@ impl Default for FireballMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct FireworksItem(pub ItemSlot); +pub struct FireworksItem(pub ItemStack); #[derive(Component, Deref, DerefMut, Clone)] pub struct AttachedToTarget(pub OptionalUnsignedInt); #[derive(Component, Deref, DerefMut, Clone)] @@ -4682,7 +4682,7 @@ impl Default for GiantMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct ItemFrameItem(pub ItemSlot); +pub struct ItemFrameItem(pub ItemStack); #[derive(Component, Deref, DerefMut, Clone)] pub struct Rotation(pub i32); #[derive(Component)] @@ -4728,7 +4728,7 @@ impl Default for GlowItemFrameMetadataBundle { pose: Pose::default(), ticks_frozen: TicksFrozen(Default::default()), }, - item_frame_item: ItemFrameItem(ItemSlot::Empty), + item_frame_item: ItemFrameItem(ItemStack::Empty), rotation: Rotation(0), }, } @@ -5521,7 +5521,7 @@ impl Default for IronGolemMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct ItemItem(pub ItemSlot); +pub struct ItemItem(pub ItemStack); #[derive(Component)] pub struct Item; impl Item { @@ -5567,7 +5567,7 @@ impl Default for ItemMetadataBundle { pose: Pose::default(), ticks_frozen: TicksFrozen(Default::default()), }, - item_item: ItemItem(ItemSlot::Empty), + item_item: ItemItem(ItemStack::Empty), } } } @@ -5603,7 +5603,7 @@ pub struct ItemDisplayHeight(pub f32); #[derive(Component, Deref, DerefMut, Clone)] pub struct ItemDisplayGlowColorOverride(pub i32); #[derive(Component, Deref, DerefMut, Clone)] -pub struct ItemDisplayItemStack(pub ItemSlot); +pub struct ItemDisplayItemStack(pub ItemStack); #[derive(Component, Deref, DerefMut, Clone)] pub struct ItemDisplayItemDisplay(pub u8); #[derive(Component)] @@ -5758,7 +5758,7 @@ impl Default for ItemDisplayMetadataBundle { item_display_width: ItemDisplayWidth(0.0), item_display_height: ItemDisplayHeight(0.0), item_display_glow_color_override: ItemDisplayGlowColorOverride(-1), - item_display_item_stack: ItemDisplayItemStack(ItemSlot::Empty), + item_display_item_stack: ItemDisplayItemStack(ItemStack::Empty), item_display_item_display: ItemDisplayItemDisplay(Default::default()), } } @@ -5813,7 +5813,7 @@ impl Default for ItemFrameMetadataBundle { pose: Pose::default(), ticks_frozen: TicksFrozen(Default::default()), }, - item_frame_item: ItemFrameItem(ItemSlot::Empty), + item_frame_item: ItemFrameItem(ItemStack::Empty), rotation: Rotation(0), } } @@ -7033,7 +7033,7 @@ impl Default for OcelotMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct OminousItemSpawnerItem(pub ItemSlot); +pub struct OminousItemSpawnerItem(pub ItemStack); #[derive(Component)] pub struct OminousItemSpawner; impl OminousItemSpawner { @@ -7079,7 +7079,7 @@ impl Default for OminousItemSpawnerMetadataBundle { pose: Pose::default(), ticks_frozen: TicksFrozen(Default::default()), }, - ominous_item_spawner_item: OminousItemSpawnerItem(ItemSlot::Empty), + ominous_item_spawner_item: OminousItemSpawnerItem(ItemStack::Empty), } } } @@ -8111,7 +8111,7 @@ impl Default for PolarBearMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct PotionItemStack(pub ItemSlot); +pub struct PotionItemStack(pub ItemStack); #[derive(Component)] pub struct Potion; impl Potion { @@ -8996,7 +8996,7 @@ impl Default for SlimeMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct SmallFireballItemStack(pub ItemSlot); +pub struct SmallFireballItemStack(pub ItemStack); #[derive(Component)] pub struct SmallFireball; impl SmallFireball { @@ -9207,7 +9207,7 @@ impl Default for SnowGolemMetadataBundle { } #[derive(Component, Deref, DerefMut, Clone)] -pub struct SnowballItemStack(pub ItemSlot); +pub struct SnowballItemStack(pub ItemStack); #[derive(Component)] pub struct Snowball; impl Snowball { diff --git a/azalea-entity/src/particle.rs b/azalea-entity/src/particle.rs index 6484b28f..fa948f85 100755 --- a/azalea-entity/src/particle.rs +++ b/azalea-entity/src/particle.rs @@ -1,13 +1,13 @@ -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use azalea_core::position::BlockPos; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use azalea_registry::ParticleKind; use bevy_ecs::component::Component; -// the order of this enum must be kept in-sync with ParticleKind, otherwise +// the order of this enum must be kept in sync with ParticleKind, otherwise // we get errors parsing particles. /// A [`ParticleKind`] with data potentially attached to it. -#[derive(Component, Clone, Debug, McBuf, Default)] +#[derive(Component, Clone, Debug, AzBuf, Default)] pub enum Particle { AngryVillager, Block(BlockParticle), @@ -44,6 +44,7 @@ pub enum Particle { Flame, Infested, CherryLeaves, + PaleOakLeaves, SculkSoul, SculkCharge(SculkChargeParticle), SculkChargePop, @@ -128,7 +129,7 @@ impl From for Particle { /// attached (like block particles), then it's set to the default. fn from(kind: ParticleKind) -> Self { // this is mostly just here so it fails to compile when a new particle is added - // to ParticleKind, since ParticleData has to be updated manually + // to ParticleKind, since `Particle` has to be updated manually match kind { ParticleKind::AngryVillager => Self::AngryVillager, ParticleKind::Block => Self::Block(BlockParticle::default()), @@ -247,12 +248,12 @@ impl From for Particle { } } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct BlockParticle { #[var] pub block_state: i32, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct DustParticle { /// Red value, 0-1 pub red: f32, @@ -264,7 +265,7 @@ pub struct DustParticle { pub scale: f32, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct DustColorTransitionParticle { /// Red value, 0-1 pub from_red: f32, @@ -282,12 +283,12 @@ pub struct DustColorTransitionParticle { pub to_blue: f32, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct ItemParticle { - pub item: ItemSlot, + pub item: ItemStack, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct VibrationParticle { pub origin: BlockPos, pub position_type: String, @@ -298,12 +299,12 @@ pub struct VibrationParticle { pub ticks: u32, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct SculkChargeParticle { pub roll: f32, } -#[derive(Debug, Clone, McBuf, Default)] +#[derive(Debug, Clone, AzBuf, Default)] pub struct ShriekParticle { #[var] pub delay: i32, // The time in ticks before the particle is displayed diff --git a/azalea-inventory/Cargo.toml b/azalea-inventory/Cargo.toml index 816df100..5633c6dd 100644 --- a/azalea-inventory/Cargo.toml +++ b/azalea-inventory/Cargo.toml @@ -4,13 +4,15 @@ edition = "2021" license = "MIT" name = "azalea-inventory" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-inventory-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] azalea-buf = { version = "0.10.0", path = "../azalea-buf" } -azalea-chat = { version = "0.10.0", path = "../azalea-chat", features = ["azalea-buf"] } +azalea-chat = { version = "0.10.0", path = "../azalea-chat", features = [ + "azalea-buf", +] } azalea-core = { version = "0.10.0", path = "../azalea-core" } azalea-inventory-macros = { version = "0.10.0", path = "./azalea-inventory-macros" } azalea-registry = { version = "0.10.0", path = "../azalea-registry" } diff --git a/azalea-inventory/azalea-inventory-macros/Cargo.toml b/azalea-inventory/azalea-inventory-macros/Cargo.toml index c55729ee..92b17e97 100644 --- a/azalea-inventory/azalea-inventory-macros/Cargo.toml +++ b/azalea-inventory/azalea-inventory-macros/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-inventory-macros" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-inventory/azalea-inventory-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [lib] proc-macro = true diff --git a/azalea-inventory/azalea-inventory-macros/src/menu_enum.rs b/azalea-inventory/azalea-inventory-macros/src/menu_enum.rs index 2b31f86c..f2236ded 100644 --- a/azalea-inventory/azalea-inventory-macros/src/menu_enum.rs +++ b/azalea-inventory/azalea-inventory-macros/src/menu_enum.rs @@ -34,11 +34,11 @@ pub fn generate(input: &DeclareMenus) -> TokenStream { } /// Player { -/// craft_result: ItemSlot, -/// craft: [ItemSlot; 4], -/// armor: [ItemSlot; 4], -/// inventory: [ItemSlot; 36], -/// offhand: ItemSlot, +/// craft_result: ItemStack, +/// craft: [ItemStack; 4], +/// armor: [ItemStack; 4], +/// inventory: [ItemStack; 36], +/// offhand: ItemStack, /// }, fn generate_variant_for_menu(menu: &Menu) -> TokenStream { let name = &menu.name; @@ -56,7 +56,7 @@ fn generate_fields(fields: &[Field], public: bool) -> TokenStream { for field in fields { let field_length = field.length; let field_type = if field.length == 1 { - quote! { ItemSlot } + quote! { ItemStack } } else { quote! { SlotList<#field_length> } }; diff --git a/azalea-inventory/azalea-inventory-macros/src/menu_impl.rs b/azalea-inventory/azalea-inventory-macros/src/menu_impl.rs index f3cc5d5c..4840f84c 100644 --- a/azalea-inventory/azalea-inventory-macros/src/menu_impl.rs +++ b/azalea-inventory/azalea-inventory-macros/src/menu_impl.rs @@ -95,11 +95,11 @@ pub fn generate(input: &DeclareMenus) -> TokenStream { impl Menu { #menu_consts - /// Get a mutable reference to the [`ItemSlot`] at the given protocol index. + /// Get a mutable reference to the [`ItemStack`] at the given protocol index. /// /// If you're trying to get an item in a menu without caring about /// protocol indexes, you should just `match` it and index the - /// [`ItemSlot`] you get. + /// [`ItemStack`] you get. /// /// Use [`Menu::slot`] if you don't need a mutable reference to the slot. /// @@ -107,24 +107,24 @@ pub fn generate(input: &DeclareMenus) -> TokenStream { /// /// Returns `None` if the index is out of bounds. #[inline] - pub fn slot_mut(&mut self, i: usize) -> Option<&mut ItemSlot> { + pub fn slot_mut(&mut self, i: usize) -> Option<&mut ItemStack> { Some(match self { #slot_mut_match_variants }) } - /// Get a reference to the [`ItemSlot`] at the given protocol index. + /// Get a reference to the [`ItemStack`] at the given protocol index. /// /// If you're trying to get an item in a menu without caring about /// protocol indexes, you should just `match` it and index the - /// [`ItemSlot`] you get. + /// [`ItemStack`] you get. /// /// Use [`Menu::slot_mut`] if you need a mutable reference to the slot. /// /// # Errors /// /// Returns `None` if the index is out of bounds. - pub fn slot(&self, i: usize) -> Option<&ItemSlot> { + pub fn slot(&self, i: usize) -> Option<&ItemStack> { Some(match self { #slot_match_variants }) @@ -153,7 +153,7 @@ pub fn generate(input: &DeclareMenus) -> TokenStream { /// /// If you *only* want to include the players inventory, then you can filter by only /// using the slots in [`Self::player_slots_range`]. - pub fn slots(&self) -> Vec { + pub fn slots(&self) -> Vec { match self { #slots_match_variants } @@ -162,7 +162,7 @@ pub fn generate(input: &DeclareMenus) -> TokenStream { /// Return the contents of the menu, not including the player's inventory. /// /// If you want to include the player's inventory, use [`Menu::slots`] instead. - pub fn contents(&self) -> Vec { + pub fn contents(&self) -> Vec { match self { #contents_match_variants } diff --git a/azalea-inventory/src/components.rs b/azalea-inventory/src/components.rs index d7adf2c9..10b00b36 100644 --- a/azalea-inventory/src/components.rs +++ b/azalea-inventory/src/components.rs @@ -1,7 +1,7 @@ use core::f64; use std::{any::Any, collections::HashMap, io::Cursor}; -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; use azalea_chat::FormattedText; use azalea_core::{position::GlobalPos, resource_location::ResourceLocation}; use azalea_registry::{ @@ -11,7 +11,7 @@ use azalea_registry::{ use simdnbt::owned::{Nbt, NbtCompound}; use uuid::Uuid; -use crate::ItemSlot; +use crate::ItemStack; pub trait DataComponent: Send + Sync + Any {} @@ -26,10 +26,10 @@ pub trait EncodableDataComponent: Send + Sync + Any { impl EncodableDataComponent for T where - T: DataComponent + Clone + McBufWritable + McBufReadable + PartialEq, + T: DataComponent + Clone + AzaleaWrite + AzaleaRead + PartialEq, { fn encode(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - self.write_into(buf) + self.azalea_write(buf) } fn clone(&self) -> Box { let cloned = self.clone(); @@ -54,105 +54,107 @@ pub fn from_kind( // note that this match statement is updated by genitemcomponents.py Ok(match kind { - DataComponentKind::CustomData => Box::new(CustomData::read_from(buf)?), - DataComponentKind::MaxStackSize => Box::new(MaxStackSize::read_from(buf)?), - DataComponentKind::MaxDamage => Box::new(MaxDamage::read_from(buf)?), - DataComponentKind::Damage => Box::new(Damage::read_from(buf)?), - DataComponentKind::Unbreakable => Box::new(Unbreakable::read_from(buf)?), - DataComponentKind::CustomName => Box::new(CustomName::read_from(buf)?), - DataComponentKind::ItemName => Box::new(ItemName::read_from(buf)?), - DataComponentKind::Lore => Box::new(Lore::read_from(buf)?), - DataComponentKind::Rarity => Box::new(Rarity::read_from(buf)?), - DataComponentKind::Enchantments => Box::new(Enchantments::read_from(buf)?), - DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::read_from(buf)?), - DataComponentKind::CanBreak => Box::new(CanBreak::read_from(buf)?), - DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::read_from(buf)?), - DataComponentKind::CustomModelData => Box::new(CustomModelData::read_from(buf)?), + DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?), + DataComponentKind::MaxStackSize => Box::new(MaxStackSize::azalea_read(buf)?), + DataComponentKind::MaxDamage => Box::new(MaxDamage::azalea_read(buf)?), + DataComponentKind::Damage => Box::new(Damage::azalea_read(buf)?), + DataComponentKind::Unbreakable => Box::new(Unbreakable::azalea_read(buf)?), + DataComponentKind::CustomName => Box::new(CustomName::azalea_read(buf)?), + DataComponentKind::ItemName => Box::new(ItemName::azalea_read(buf)?), + DataComponentKind::Lore => Box::new(Lore::azalea_read(buf)?), + DataComponentKind::Rarity => Box::new(Rarity::azalea_read(buf)?), + DataComponentKind::Enchantments => Box::new(Enchantments::azalea_read(buf)?), + DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::azalea_read(buf)?), + DataComponentKind::CanBreak => Box::new(CanBreak::azalea_read(buf)?), + DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::azalea_read(buf)?), + DataComponentKind::CustomModelData => Box::new(CustomModelData::azalea_read(buf)?), DataComponentKind::HideAdditionalTooltip => { - Box::new(HideAdditionalTooltip::read_from(buf)?) + Box::new(HideAdditionalTooltip::azalea_read(buf)?) } - DataComponentKind::HideTooltip => Box::new(HideTooltip::read_from(buf)?), - DataComponentKind::RepairCost => Box::new(RepairCost::read_from(buf)?), - DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::read_from(buf)?), + DataComponentKind::HideTooltip => Box::new(HideTooltip::azalea_read(buf)?), + DataComponentKind::RepairCost => Box::new(RepairCost::azalea_read(buf)?), + DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::azalea_read(buf)?), DataComponentKind::EnchantmentGlintOverride => { - Box::new(EnchantmentGlintOverride::read_from(buf)?) + Box::new(EnchantmentGlintOverride::azalea_read(buf)?) } - DataComponentKind::IntangibleProjectile => Box::new(IntangibleProjectile::read_from(buf)?), - DataComponentKind::Food => Box::new(Food::read_from(buf)?), - DataComponentKind::Tool => Box::new(Tool::read_from(buf)?), - DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::read_from(buf)?), - DataComponentKind::DyedColor => Box::new(DyedColor::read_from(buf)?), - DataComponentKind::MapColor => Box::new(MapColor::read_from(buf)?), - DataComponentKind::MapId => Box::new(MapId::read_from(buf)?), - DataComponentKind::MapDecorations => Box::new(MapDecorations::read_from(buf)?), - DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::read_from(buf)?), - DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::read_from(buf)?), - DataComponentKind::BundleContents => Box::new(BundleContents::read_from(buf)?), - DataComponentKind::PotionContents => Box::new(PotionContents::read_from(buf)?), + DataComponentKind::IntangibleProjectile => { + Box::new(IntangibleProjectile::azalea_read(buf)?) + } + DataComponentKind::Food => Box::new(Food::azalea_read(buf)?), + DataComponentKind::Tool => Box::new(Tool::azalea_read(buf)?), + DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::azalea_read(buf)?), + DataComponentKind::DyedColor => Box::new(DyedColor::azalea_read(buf)?), + DataComponentKind::MapColor => Box::new(MapColor::azalea_read(buf)?), + DataComponentKind::MapId => Box::new(MapId::azalea_read(buf)?), + DataComponentKind::MapDecorations => Box::new(MapDecorations::azalea_read(buf)?), + DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::azalea_read(buf)?), + DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::azalea_read(buf)?), + DataComponentKind::BundleContents => Box::new(BundleContents::azalea_read(buf)?), + DataComponentKind::PotionContents => Box::new(PotionContents::azalea_read(buf)?), DataComponentKind::SuspiciousStewEffects => { - Box::new(SuspiciousStewEffects::read_from(buf)?) + Box::new(SuspiciousStewEffects::azalea_read(buf)?) } - DataComponentKind::WritableBookContent => Box::new(WritableBookContent::read_from(buf)?), - DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::read_from(buf)?), - DataComponentKind::Trim => Box::new(Trim::read_from(buf)?), - DataComponentKind::DebugStickState => Box::new(DebugStickState::read_from(buf)?), - DataComponentKind::EntityData => Box::new(EntityData::read_from(buf)?), - DataComponentKind::BucketEntityData => Box::new(BucketEntityData::read_from(buf)?), - DataComponentKind::BlockEntityData => Box::new(BlockEntityData::read_from(buf)?), - DataComponentKind::Instrument => Box::new(Instrument::read_from(buf)?), + DataComponentKind::WritableBookContent => Box::new(WritableBookContent::azalea_read(buf)?), + DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::azalea_read(buf)?), + DataComponentKind::Trim => Box::new(Trim::azalea_read(buf)?), + DataComponentKind::DebugStickState => Box::new(DebugStickState::azalea_read(buf)?), + DataComponentKind::EntityData => Box::new(EntityData::azalea_read(buf)?), + DataComponentKind::BucketEntityData => Box::new(BucketEntityData::azalea_read(buf)?), + DataComponentKind::BlockEntityData => Box::new(BlockEntityData::azalea_read(buf)?), + DataComponentKind::Instrument => Box::new(Instrument::azalea_read(buf)?), DataComponentKind::OminousBottleAmplifier => { - Box::new(OminousBottleAmplifier::read_from(buf)?) + Box::new(OminousBottleAmplifier::azalea_read(buf)?) } - DataComponentKind::Recipes => Box::new(Recipes::read_from(buf)?), - DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::read_from(buf)?), - DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::read_from(buf)?), - DataComponentKind::Fireworks => Box::new(Fireworks::read_from(buf)?), - DataComponentKind::Profile => Box::new(Profile::read_from(buf)?), - DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::read_from(buf)?), - DataComponentKind::BannerPatterns => Box::new(BannerPatterns::read_from(buf)?), - DataComponentKind::BaseColor => Box::new(BaseColor::read_from(buf)?), - DataComponentKind::PotDecorations => Box::new(PotDecorations::read_from(buf)?), - DataComponentKind::Container => Box::new(Container::read_from(buf)?), - DataComponentKind::BlockState => Box::new(BlockState::read_from(buf)?), - DataComponentKind::Bees => Box::new(Bees::read_from(buf)?), - DataComponentKind::Lock => Box::new(Lock::read_from(buf)?), - DataComponentKind::ContainerLoot => Box::new(ContainerLoot::read_from(buf)?), - DataComponentKind::JukeboxPlayable => Box::new(JukeboxPlayable::read_from(buf)?), - DataComponentKind::Consumable => Box::new(Consumable::read_from(buf)?), - DataComponentKind::UseRemainder => Box::new(UseRemainder::read_from(buf)?), - DataComponentKind::UseCooldown => Box::new(UseCooldown::read_from(buf)?), - DataComponentKind::Enchantable => Box::new(Enchantable::read_from(buf)?), - DataComponentKind::Repairable => Box::new(Repairable::read_from(buf)?), - DataComponentKind::ItemModel => Box::new(ItemModel::read_from(buf)?), - DataComponentKind::DamageResistant => Box::new(DamageResistant::read_from(buf)?), - DataComponentKind::Equippable => Box::new(Equippable::read_from(buf)?), - DataComponentKind::Glider => Box::new(Glider::read_from(buf)?), - DataComponentKind::TooltipStyle => Box::new(TooltipStyle::read_from(buf)?), - DataComponentKind::DeathProtection => Box::new(DeathProtection::read_from(buf)?), + DataComponentKind::Recipes => Box::new(Recipes::azalea_read(buf)?), + DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::azalea_read(buf)?), + DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::azalea_read(buf)?), + DataComponentKind::Fireworks => Box::new(Fireworks::azalea_read(buf)?), + DataComponentKind::Profile => Box::new(Profile::azalea_read(buf)?), + DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::azalea_read(buf)?), + DataComponentKind::BannerPatterns => Box::new(BannerPatterns::azalea_read(buf)?), + DataComponentKind::BaseColor => Box::new(BaseColor::azalea_read(buf)?), + DataComponentKind::PotDecorations => Box::new(PotDecorations::azalea_read(buf)?), + DataComponentKind::Container => Box::new(Container::azalea_read(buf)?), + DataComponentKind::BlockState => Box::new(BlockState::azalea_read(buf)?), + DataComponentKind::Bees => Box::new(Bees::azalea_read(buf)?), + DataComponentKind::Lock => Box::new(Lock::azalea_read(buf)?), + DataComponentKind::ContainerLoot => Box::new(ContainerLoot::azalea_read(buf)?), + DataComponentKind::JukeboxPlayable => Box::new(JukeboxPlayable::azalea_read(buf)?), + DataComponentKind::Consumable => Box::new(Consumable::azalea_read(buf)?), + DataComponentKind::UseRemainder => Box::new(UseRemainder::azalea_read(buf)?), + DataComponentKind::UseCooldown => Box::new(UseCooldown::azalea_read(buf)?), + DataComponentKind::Enchantable => Box::new(Enchantable::azalea_read(buf)?), + DataComponentKind::Repairable => Box::new(Repairable::azalea_read(buf)?), + DataComponentKind::ItemModel => Box::new(ItemModel::azalea_read(buf)?), + DataComponentKind::DamageResistant => Box::new(DamageResistant::azalea_read(buf)?), + DataComponentKind::Equippable => Box::new(Equippable::azalea_read(buf)?), + DataComponentKind::Glider => Box::new(Glider::azalea_read(buf)?), + DataComponentKind::TooltipStyle => Box::new(TooltipStyle::azalea_read(buf)?), + DataComponentKind::DeathProtection => Box::new(DeathProtection::azalea_read(buf)?), }) } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CustomData { pub nbt: Nbt, } impl DataComponent for CustomData {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MaxStackSize { #[var] pub count: i32, } impl DataComponent for MaxStackSize {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MaxDamage { #[var] pub amount: i32, } impl DataComponent for MaxDamage {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Damage { #[var] pub amount: i32, @@ -160,7 +162,7 @@ pub struct Damage { impl DataComponent for Damage {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Unbreakable { pub show_in_tooltip: bool, } @@ -173,26 +175,26 @@ impl Default for Unbreakable { } } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CustomName { pub name: FormattedText, } impl DataComponent for CustomName {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct ItemName { pub name: FormattedText, } impl DataComponent for ItemName {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Lore { pub lines: Vec, // vanilla also has styled_lines here but it doesn't appear to be used for the protocol } impl DataComponent for Lore {} -#[derive(Clone, PartialEq, Copy, McBuf)] +#[derive(Clone, PartialEq, Copy, AzBuf)] pub enum Rarity { Common, Uncommon, @@ -201,7 +203,7 @@ pub enum Rarity { } impl DataComponent for Rarity {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Enchantments { #[var] pub levels: HashMap, @@ -209,7 +211,7 @@ pub struct Enchantments { } impl DataComponent for Enchantments {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub enum BlockStateValueMatcher { Exact { value: String, @@ -220,38 +222,38 @@ pub enum BlockStateValueMatcher { }, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BlockStatePropertyMatcher { pub name: String, pub value_matcher: BlockStateValueMatcher, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BlockPredicate { pub blocks: Option>, pub properties: Option>, pub nbt: Option, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct AdventureModePredicate { pub predicates: Vec, pub show_in_tooltip: bool, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CanPlaceOn { pub predicate: AdventureModePredicate, } impl DataComponent for CanPlaceOn {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CanBreak { pub predicate: AdventureModePredicate, } impl DataComponent for CanBreak {} -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum EquipmentSlotGroup { Any, Mainhand, @@ -265,7 +267,7 @@ pub enum EquipmentSlotGroup { Body, } -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum AttributeModifierOperation { Addition, MultiplyBase, @@ -275,7 +277,7 @@ pub enum AttributeModifierOperation { // this is duplicated in azalea-entity, BUT the one there has a different // protocol format (and we can't use it anyways because it would cause a // circular dependency) -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct AttributeModifier { pub uuid: Uuid, pub name: String, @@ -283,57 +285,57 @@ pub struct AttributeModifier { pub operation: AttributeModifierOperation, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct AttributeModifiersEntry { pub attribute: Attribute, pub modifier: AttributeModifier, pub slot: EquipmentSlotGroup, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct AttributeModifiers { pub modifiers: Vec, pub show_in_tooltip: bool, } impl DataComponent for AttributeModifiers {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CustomModelData { #[var] pub value: i32, } impl DataComponent for CustomModelData {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct HideAdditionalTooltip; impl DataComponent for HideAdditionalTooltip {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct HideTooltip; impl DataComponent for HideTooltip {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct RepairCost { #[var] pub cost: u32, } impl DataComponent for RepairCost {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct CreativeSlotLock; impl DataComponent for CreativeSlotLock {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct EnchantmentGlintOverride { pub show_glint: bool, } impl DataComponent for EnchantmentGlintOverride {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct IntangibleProjectile; impl DataComponent for IntangibleProjectile {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MobEffectDetails { #[var] pub amplifier: i32, @@ -345,19 +347,19 @@ pub struct MobEffectDetails { pub hidden_effect: Option>, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MobEffectInstance { pub effect: MobEffect, pub details: MobEffectDetails, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct PossibleEffect { pub effect: MobEffectInstance, pub probability: f32, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Food { #[var] pub nutrition: i32, @@ -368,14 +370,14 @@ pub struct Food { } impl DataComponent for Food {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct ToolRule { pub blocks: HolderSet, pub speed: Option, pub correct_for_drops: Option, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Tool { pub rules: Vec, pub default_mining_speed: f32, @@ -384,7 +386,7 @@ pub struct Tool { } impl DataComponent for Tool {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct StoredEnchantments { #[var] pub enchantments: HashMap, @@ -392,52 +394,52 @@ pub struct StoredEnchantments { } impl DataComponent for StoredEnchantments {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct DyedColor { pub rgb: i32, pub show_in_tooltip: bool, } impl DataComponent for DyedColor {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MapColor { pub color: i32, } impl DataComponent for MapColor {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MapId { #[var] pub id: i32, } impl DataComponent for MapId {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct MapDecorations { pub decorations: NbtCompound, } impl DataComponent for MapDecorations {} -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum MapPostProcessing { Lock, Scale, } impl DataComponent for MapPostProcessing {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct ChargedProjectiles { - pub items: Vec, + pub items: Vec, } impl DataComponent for ChargedProjectiles {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BundleContents { - pub items: Vec, + pub items: Vec, } impl DataComponent for BundleContents {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct PotionContents { pub potion: Option, pub custom_color: Option, @@ -445,26 +447,26 @@ pub struct PotionContents { } impl DataComponent for PotionContents {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct SuspiciousStewEffect { pub effect: MobEffect, #[var] pub duration: i32, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct SuspiciousStewEffects { pub effects: Vec, } impl DataComponent for SuspiciousStewEffects {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct WritableBookContent { pub pages: Vec, } impl DataComponent for WritableBookContent {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct WrittenBookContent { pub title: String, pub author: String, @@ -475,7 +477,7 @@ pub struct WrittenBookContent { } impl DataComponent for WrittenBookContent {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Trim { pub material: TrimMaterial, pub pattern: TrimPattern, @@ -483,57 +485,57 @@ pub struct Trim { } impl DataComponent for Trim {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct DebugStickState { pub properties: NbtCompound, } impl DataComponent for DebugStickState {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct EntityData { pub entity: NbtCompound, } impl DataComponent for EntityData {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BucketEntityData { pub entity: NbtCompound, } impl DataComponent for BucketEntityData {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BlockEntityData { pub entity: NbtCompound, } impl DataComponent for BlockEntityData {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Instrument { pub instrument: azalea_registry::Instrument, } impl DataComponent for Instrument {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct OminousBottleAmplifier { #[var] pub amplifier: i32, } impl DataComponent for OminousBottleAmplifier {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Recipes { pub recipes: Vec, } impl DataComponent for Recipes {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct LodestoneTracker { pub target: Option, pub tracked: bool, } impl DataComponent for LodestoneTracker {} -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum FireworkExplosionShape { SmallBall, LargeBall, @@ -542,7 +544,7 @@ pub enum FireworkExplosionShape { Burst, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct FireworkExplosion { pub shape: FireworkExplosionShape, pub colors: Vec, @@ -552,7 +554,7 @@ pub struct FireworkExplosion { } impl DataComponent for FireworkExplosion {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Fireworks { #[var] pub flight_duration: i32, @@ -560,14 +562,14 @@ pub struct Fireworks { } impl DataComponent for Fireworks {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct GameProfileProperty { pub name: String, pub value: String, pub signature: Option, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Profile { pub name: String, pub id: Option, @@ -575,13 +577,13 @@ pub struct Profile { } impl DataComponent for Profile {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct NoteBlockSound { pub sound: ResourceLocation, } impl DataComponent for NoteBlockSound {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BannerPattern { #[var] pub pattern: i32, @@ -589,13 +591,13 @@ pub struct BannerPattern { pub color: i32, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BannerPatterns { pub patterns: Vec, } impl DataComponent for BannerPatterns {} -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum DyeColor { White, Orange, @@ -615,31 +617,31 @@ pub enum DyeColor { Black, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BaseColor { pub color: DyeColor, } impl DataComponent for BaseColor {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct PotDecorations { pub items: Vec, } impl DataComponent for PotDecorations {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Container { - pub items: Vec, + pub items: Vec, } impl DataComponent for Container {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BlockState { pub properties: HashMap, } impl DataComponent for BlockState {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct BeehiveOccupant { pub entity_data: NbtCompound, #[var] @@ -648,32 +650,32 @@ pub struct BeehiveOccupant { pub min_ticks_in_hive: i32, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Bees { pub occupants: Vec, } impl DataComponent for Bees {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Lock { pub key: String, } impl DataComponent for Lock {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct ContainerLoot { pub loot: NbtCompound, } impl DataComponent for ContainerLoot {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct JukeboxPlayable { pub song: azalea_registry::JukeboxSong, pub show_in_tooltip: bool, } impl DataComponent for JukeboxPlayable {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Consumable { pub consume_seconds: f32, pub animation: ItemUseAnimation, @@ -683,7 +685,7 @@ pub struct Consumable { } impl DataComponent for Consumable {} -#[derive(Clone, Copy, PartialEq, McBuf)] +#[derive(Clone, Copy, PartialEq, AzBuf)] pub enum ItemUseAnimation { None, Eat, @@ -697,39 +699,39 @@ pub enum ItemUseAnimation { Brush, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct UseRemainder { - pub convert_into: ItemSlot, + pub convert_into: ItemStack, } impl DataComponent for UseRemainder {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct UseCooldown { pub seconds: f32, pub cooldown_group: Option, } impl DataComponent for UseCooldown {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Enchantable { #[var] pub value: u32, } impl DataComponent for Enchantable {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Repairable { pub items: HolderSet, } impl DataComponent for Repairable {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct ItemModel { pub resource_location: ResourceLocation, } impl DataComponent for ItemModel {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct DamageResistant { // in the vanilla code this is // ``` @@ -743,7 +745,7 @@ pub struct DamageResistant { } impl DataComponent for DamageResistant {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Equippable { pub slot: EquipmentSlot, pub equip_sound: SoundEvent, @@ -752,7 +754,7 @@ pub struct Equippable { } impl DataComponent for Equippable {} -#[derive(Clone, Copy, Debug, PartialEq, McBuf)] +#[derive(Clone, Copy, Debug, PartialEq, AzBuf)] pub enum EquipmentSlot { Mainhand, Offhand, @@ -765,17 +767,17 @@ pub enum EquipmentSlot { Body, } -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct Glider; impl DataComponent for Glider {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct TooltipStyle { pub resource_location: ResourceLocation, } impl DataComponent for TooltipStyle {} -#[derive(Clone, PartialEq, McBuf)] +#[derive(Clone, PartialEq, AzBuf)] pub struct DeathProtection { pub death_effects: Vec, } diff --git a/azalea-inventory/src/item/mod.rs b/azalea-inventory/src/item/mod.rs index 862cd20e..7f077c6a 100644 --- a/azalea-inventory/src/item/mod.rs +++ b/azalea-inventory/src/item/mod.rs @@ -2,9 +2,9 @@ pub trait MaxStackSizeExt { /// Get the maximum stack size for this item. /// /// This is a signed integer to be consistent with the `count` field of - /// [`ItemSlotData`]. + /// [`ItemStackData`]. /// - /// [`ItemSlotData`]: crate::ItemSlotData + /// [`ItemStackData`]: crate::ItemStackData fn max_stack_size(&self) -> i32; /// Whether this item can be stacked with other items. diff --git a/azalea-inventory/src/lib.rs b/azalea-inventory/src/lib.rs index 930c1a5d..3f9ba237 100644 --- a/azalea-inventory/src/lib.rs +++ b/azalea-inventory/src/lib.rs @@ -9,17 +9,17 @@ mod slot; use std::ops::{Deref, DerefMut, RangeInclusive}; use azalea_inventory_macros::declare_menus; -pub use slot::{DataComponentPatch, ItemSlot, ItemSlotData}; +pub use slot::{DataComponentPatch, ItemStack, ItemStackData}; // TODO: remove this here and in azalea-inventory-macros when rust makes // Default be implemented for all array sizes // https://github.com/rust-lang/rust/issues/61415 -/// A fixed-size list of [`ItemSlot`]s. +/// A fixed-size list of [`ItemStack`]s. #[derive(Debug, Clone)] -pub struct SlotList([ItemSlot; N]); +pub struct SlotList([ItemStack; N]); impl Deref for SlotList { - type Target = [ItemSlot; N]; + type Target = [ItemStack; N]; fn deref(&self) -> &Self::Target { &self.0 } @@ -31,7 +31,7 @@ impl DerefMut for SlotList { } impl Default for SlotList { fn default() -> Self { - SlotList([(); N].map(|_| ItemSlot::Empty)) + SlotList([(); N].map(|_| ItemStack::Empty)) } } diff --git a/azalea-inventory/src/operations.rs b/azalea-inventory/src/operations.rs index 652d1900..0df7c794 100644 --- a/azalea-inventory/src/operations.rs +++ b/azalea-inventory/src/operations.rs @@ -1,6 +1,6 @@ use std::ops::RangeInclusive; -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use crate::{ item::MaxStackSizeExt, AnvilMenuLocation, BeaconMenuLocation, BlastFurnaceMenuLocation, @@ -8,7 +8,7 @@ use crate::{ CraftingMenuLocation, EnchantmentMenuLocation, FurnaceMenuLocation, Generic3x3MenuLocation, Generic9x1MenuLocation, Generic9x2MenuLocation, Generic9x3MenuLocation, Generic9x4MenuLocation, Generic9x5MenuLocation, Generic9x6MenuLocation, GrindstoneMenuLocation, HopperMenuLocation, - ItemSlot, ItemSlotData, LecternMenuLocation, LoomMenuLocation, Menu, MenuLocation, + ItemStack, ItemStackData, LecternMenuLocation, LoomMenuLocation, Menu, MenuLocation, MerchantMenuLocation, Player, PlayerMenuLocation, ShulkerBoxMenuLocation, SmithingMenuLocation, SmokerMenuLocation, StonecutterMenuLocation, }; @@ -250,7 +250,7 @@ impl ClickOperation { } } -#[derive(McBuf, Clone, Copy, Debug)] +#[derive(AzBuf, Clone, Copy, Debug)] pub enum ClickType { Pickup = 0, QuickMove = 1, @@ -266,10 +266,10 @@ impl Menu { /// /// Keep in mind that this doesn't send any packets to the server, it just /// mutates this specific `Menu`. - pub fn quick_move_stack(&mut self, slot_index: usize) -> ItemSlot { + pub fn quick_move_stack(&mut self, slot_index: usize) -> ItemStack { let slot = self.slot(slot_index); if slot.is_none() { - return ItemSlot::Empty; + return ItemStack::Empty; }; let slot_location = self @@ -587,7 +587,7 @@ impl Menu { }, } - ItemSlot::Empty + ItemStack::Empty } fn try_move_item_to_slots_or_toggle_hotbar( @@ -610,7 +610,7 @@ impl Menu { /// Whether the given item could be placed in this menu. /// /// TODO: right now this always returns true - pub fn may_place(&self, _target_slot_index: usize, _item: &ItemSlotData) -> bool { + pub fn may_place(&self, _target_slot_index: usize, _item: &ItemStackData) -> bool { true } @@ -662,14 +662,14 @@ impl Menu { /// slot is present and the same item. fn move_item_to_slot_if_stackable( &mut self, - item_slot: &mut ItemSlot, + item_slot: &mut ItemStack, target_slot_index: usize, ) { - let ItemSlot::Present(item) = item_slot else { + let ItemStack::Present(item) = item_slot else { return; }; let target_slot = self.slot(target_slot_index).unwrap(); - if let ItemSlot::Present(target_item) = target_slot { + if let ItemStack::Present(target_item) = target_slot { // the target slot is empty, so we can just move the item there if self.may_place(target_slot_index, item) && target_item.is_same_item_and_components(item) @@ -679,15 +679,15 @@ impl Menu { // get the target slot again but mut this time so we can update it let target_slot = self.slot_mut(target_slot_index).unwrap(); - *target_slot = ItemSlot::Present(new_target_slot_data); + *target_slot = ItemStack::Present(new_target_slot_data); item_slot.update_empty(); } } } - fn move_item_to_slot_if_empty(&mut self, item_slot: &mut ItemSlot, target_slot_index: usize) { - let ItemSlot::Present(item) = item_slot else { + fn move_item_to_slot_if_empty(&mut self, item_slot: &mut ItemStack, target_slot_index: usize) { + let ItemStack::Present(item) = item_slot else { return; }; let target_slot = self.slot(target_slot_index).unwrap(); @@ -696,7 +696,7 @@ impl Menu { let new_target_slot_data = item.split(u32::min(slot_item_limit, item.count as u32)); let target_slot = self.slot_mut(target_slot_index).unwrap(); - *target_slot = ItemSlot::Present(new_target_slot_data); + *target_slot = ItemStack::Present(new_target_slot_data); item_slot.update_empty(); } } diff --git a/azalea-inventory/src/slot.rs b/azalea-inventory/src/slot.rs index 601c28e2..7d62bf69 100644 --- a/azalea-inventory/src/slot.rs +++ b/azalea-inventory/src/slot.rs @@ -4,34 +4,34 @@ use std::{ io::{Cursor, Write}, }; -use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use azalea_registry::DataComponentKind; use crate::components::{self}; /// Either an item in an inventory or nothing. #[derive(Debug, Clone, Default, PartialEq)] -pub enum ItemSlot { +pub enum ItemStack { #[default] Empty, - Present(ItemSlotData), + Present(ItemStackData), } -impl ItemSlot { - /// Check if the slot is ItemSlot::Empty, if the count is <= 0, or if the +impl ItemStack { + /// Check if the slot is ItemStack::Empty, if the count is <= 0, or if the /// item is air. /// - /// This is the opposite of [`ItemSlot::is_present`]. + /// This is the opposite of [`ItemStack::is_present`]. pub fn is_empty(&self) -> bool { match self { - ItemSlot::Empty => true, - ItemSlot::Present(item) => item.is_empty(), + ItemStack::Empty => true, + ItemStack::Present(item) => item.is_empty(), } } - /// Check if the slot is not ItemSlot::Empty, if the count is > 0, and if + /// Check if the slot is not ItemStack::Empty, if the count is > 0, and if /// the item is not air. /// - /// This is the opposite of [`ItemSlot::is_empty`]. + /// This is the opposite of [`ItemStack::is_empty`]. pub fn is_present(&self) -> bool { !self.is_empty() } @@ -42,21 +42,21 @@ impl ItemSlot { /// slot is present. pub fn count(&self) -> i32 { match self { - ItemSlot::Empty => 0, - ItemSlot::Present(i) => i.count, + ItemStack::Empty => 0, + ItemStack::Present(i) => i.count, } } /// Remove `count` items from this slot, returning the removed items. - pub fn split(&mut self, count: u32) -> ItemSlot { + pub fn split(&mut self, count: u32) -> ItemStack { match self { - ItemSlot::Empty => ItemSlot::Empty, - ItemSlot::Present(i) => { + ItemStack::Empty => ItemStack::Empty, + ItemStack::Present(i) => { let returning = i.split(count); if i.is_empty() { - *self = ItemSlot::Empty; + *self = ItemStack::Empty; } - ItemSlot::Present(returning) + ItemStack::Present(returning) } } } @@ -65,33 +65,33 @@ impl ItemSlot { /// [`azalea_registry::Item::Air`] pub fn kind(&self) -> azalea_registry::Item { match self { - ItemSlot::Empty => azalea_registry::Item::Air, - ItemSlot::Present(i) => i.kind, + ItemStack::Empty => azalea_registry::Item::Air, + ItemStack::Present(i) => i.kind, } } /// Update whether this slot is empty, based on the count. pub fn update_empty(&mut self) { - if let ItemSlot::Present(i) = self { + if let ItemStack::Present(i) = self { if i.is_empty() { - *self = ItemSlot::Empty; + *self = ItemStack::Empty; } } } - /// Convert this slot into an [`ItemSlotData`], if it's present. - pub fn as_present(&self) -> Option<&ItemSlotData> { + /// Convert this slot into an [`ItemStackData`], if it's present. + pub fn as_present(&self) -> Option<&ItemStackData> { match self { - ItemSlot::Empty => None, - ItemSlot::Present(i) => Some(i), + ItemStack::Empty => None, + ItemStack::Present(i) => Some(i), } } } -/// An item in an inventory, with a count and NBT. Usually you want [`ItemSlot`] -/// or [`azalea_registry::Item`] instead. +/// An item in an inventory, with a count and NBT. Usually you want +/// [`ItemStack`] or [`azalea_registry::Item`] instead. #[derive(Debug, Clone, PartialEq)] -pub struct ItemSlotData { +pub struct ItemStackData { /// The amount of the item in this slot. /// /// The count can be zero or negative, but this is rare. @@ -100,9 +100,9 @@ pub struct ItemSlotData { pub components: DataComponentPatch, } -impl ItemSlotData { +impl ItemStackData { /// Remove `count` items from this slot, returning the removed items. - pub fn split(&mut self, count: u32) -> ItemSlotData { + pub fn split(&mut self, count: u32) -> ItemStackData { let returning_count = i32::min(count as i32, self.count); let mut returning = self.clone(); returning.count = returning_count; @@ -118,14 +118,14 @@ impl ItemSlotData { /// Whether this item is the same as another item, ignoring the count. /// /// ``` - /// # use azalea_inventory::ItemSlotData; + /// # use azalea_inventory::ItemStackData; /// # use azalea_registry::Item; - /// let mut a = ItemSlotData { + /// let mut a = ItemStackData { /// kind: Item::Stone, /// count: 1, /// components: Default::default(), /// }; - /// let mut b = ItemSlotData { + /// let mut b = ItemStackData { /// kind: Item::Stone, /// count: 2, /// components: Default::default(), @@ -135,20 +135,20 @@ impl ItemSlotData { /// b.kind = Item::Dirt; /// assert!(!a.is_same_item_and_components(&b)); /// ``` - pub fn is_same_item_and_components(&self, other: &ItemSlotData) -> bool { + pub fn is_same_item_and_components(&self, other: &ItemStackData) -> bool { self.kind == other.kind && self.components == other.components } } -impl McBufReadable for ItemSlot { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let count = i32::var_read_from(buf)?; +impl AzaleaRead for ItemStack { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let count = i32::azalea_read_var(buf)?; if count <= 0 { - Ok(ItemSlot::Empty) + Ok(ItemStack::Empty) } else { - let kind = azalea_registry::Item::read_from(buf)?; - let components = DataComponentPatch::read_from(buf)?; - Ok(ItemSlot::Present(ItemSlotData { + let kind = azalea_registry::Item::azalea_read(buf)?; + let components = DataComponentPatch::azalea_read(buf)?; + Ok(ItemStack::Present(ItemStackData { count, kind, components, @@ -157,14 +157,14 @@ impl McBufReadable for ItemSlot { } } -impl McBufWritable for ItemSlot { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for ItemStack { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { - ItemSlot::Empty => 0.var_write_into(buf)?, - ItemSlot::Present(i) => { - i.count.var_write_into(buf)?; - i.kind.write_into(buf)?; - i.components.write_into(buf)?; + ItemStack::Empty => 0.azalea_write_var(buf)?, + ItemStack::Present(i) => { + i.count.azalea_write_var(buf)?; + i.kind.azalea_write(buf)?; + i.components.azalea_write(buf)?; } }; Ok(()) @@ -182,10 +182,10 @@ impl DataComponentPatch { } } -impl McBufReadable for DataComponentPatch { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let components_with_data_count = u32::var_read_from(buf)?; - let components_without_data_count = u32::var_read_from(buf)?; +impl AzaleaRead for DataComponentPatch { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let components_with_data_count = u32::azalea_read_var(buf)?; + let components_without_data_count = u32::azalea_read_var(buf)?; if components_without_data_count == 0 && components_with_data_count == 0 { return Ok(DataComponentPatch::default()); @@ -193,13 +193,13 @@ impl McBufReadable for DataComponentPatch { let mut components = HashMap::new(); for _ in 0..components_with_data_count { - let component_kind = DataComponentKind::read_from(buf)?; + let component_kind = DataComponentKind::azalea_read(buf)?; let component_data = components::from_kind(component_kind, buf)?; components.insert(component_kind, Some(component_data)); } for _ in 0..components_without_data_count { - let component_kind = DataComponentKind::read_from(buf)?; + let component_kind = DataComponentKind::azalea_read(buf)?; components.insert(component_kind, None); } @@ -207,8 +207,8 @@ impl McBufReadable for DataComponentPatch { } } -impl McBufWritable for DataComponentPatch { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for DataComponentPatch { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut components_with_data_count = 0; let mut components_without_data_count = 0; for component in self.components.values() { @@ -219,21 +219,21 @@ impl McBufWritable for DataComponentPatch { } } - components_with_data_count.write_into(buf)?; - components_without_data_count.write_into(buf)?; + components_with_data_count.azalea_write(buf)?; + components_without_data_count.azalea_write(buf)?; for (kind, component) in &self.components { if let Some(component) = component { - kind.write_into(buf)?; + kind.azalea_write(buf)?; let mut component_buf = Vec::new(); component.encode(&mut component_buf).unwrap(); - component_buf.write_into(buf)?; + component_buf.azalea_write(buf)?; } } for (kind, component) in &self.components { if component.is_none() { - kind.write_into(buf)?; + kind.azalea_write(buf)?; } } diff --git a/azalea-language/Cargo.toml b/azalea-language/Cargo.toml index bdc7bb4e..2038f31e 100644 --- a/azalea-language/Cargo.toml +++ b/azalea-language/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-language" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-language" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-physics/Cargo.toml b/azalea-physics/Cargo.toml index fe4e925a..d668db1b 100644 --- a/azalea-physics/Cargo.toml +++ b/azalea-physics/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-physics" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-physics" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-physics/src/clip.rs b/azalea-physics/src/clip.rs index 30b46a8e..f24721c5 100644 --- a/azalea-physics/src/clip.rs +++ b/azalea-physics/src/clip.rs @@ -5,7 +5,7 @@ use azalea_core::{ math::{self, lerp, EPSILON}, position::{BlockPos, Vec3}, }; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use azalea_world::ChunkStorage; use bevy_ecs::entity::Entity; @@ -52,7 +52,7 @@ pub enum FluidPickType { pub struct EntityCollisionContext { pub descending: bool, pub entity_bottom: f64, - pub held_item: ItemSlot, + pub held_item: ItemStack, // pub can_stand_on_fluid: Box bool>, pub entity: Entity, } @@ -62,21 +62,15 @@ pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResul context.from, context.to, context, - |context, block_pos| { + |ctx, block_pos| { let block_state = chunk_storage.get_block_state(block_pos).unwrap_or_default(); // TODO: add fluid stuff to this (see getFluidState in vanilla source) - let block_shape = context.block_shape(block_state); - clip_with_interaction_override( - &context.from, - &context.to, - block_pos, - block_shape, - &block_state, - ) + let block_shape = ctx.block_shape(block_state); + clip_with_interaction_override(&ctx.from, &ctx.to, block_pos, block_shape, &block_state) // let block_distance = if let Some(block_hit_result) = - // block_hit_result { context.from.distance_to_sqr(& + // block_hit_result { context.from.distance_squared_to(& // block_hit_result.location) } else { - // f64::MAX + // f64::INFINITY // }; }, |context| { @@ -90,19 +84,6 @@ pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResul ) } -// default BlockHitResult clipWithInteractionOverride(Vec3 world, Vec3 from, -// BlockPos to, VoxelShape shape, BlockState block) { -// BlockHitResult blockHitResult = shape.clip(world, from, to); -// if (blockHitResult != null) { -// BlockHitResult var7 = block.getInteractionShape(this, to).clip(world, -// from, to); if (var7 != null -// && var7.getLocation().subtract(world).lengthSqr() < -// blockHitResult.getLocation().subtract(world).lengthSqr()) { return -// blockHitResult.withDirection(var7.getDirection()); } -// } - -// return blockHitResult; -// } fn clip_with_interaction_override( from: &Vec3, to: &Vec3, @@ -119,8 +100,8 @@ fn clip_with_interaction_override( let interaction_shape = block_state.shape(); let interaction_hit_result = interaction_shape.clip(from, to, block_pos); if let Some(interaction_hit_result) = interaction_hit_result { - if interaction_hit_result.location.distance_to_sqr(from) - < block_hit_result.location.distance_to_sqr(from) + if interaction_hit_result.location.distance_squared_to(from) + < block_hit_result.location.distance_squared_to(from) { return Some(block_hit_result.with_direction(interaction_hit_result.direction)); } diff --git a/azalea-physics/src/collision/blocks.rs b/azalea-physics/src/collision/blocks.rs index 73d62a41..d3c976ac 100644 --- a/azalea-physics/src/collision/blocks.rs +++ b/azalea-physics/src/collision/blocks.rs @@ -1,6 +1,6 @@ //! Autogenerated block collisions for every block -// This file is generated from codegen/lib/code/block_shapes.py. If you want to +// This file is generated from codegen/lib/code/shapes.py. If you want to // modify it, change that file. #![allow(clippy::explicit_auto_deref)] @@ -1776,19 +1776,21 @@ impl BlockWithShape for BlockState { } } -static SHAPES_MAP: [&LazyLock; 26644] = [ +static SHAPES_MAP: [&LazyLock; 27113] = [ &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, @@ -1945,48 +1947,51 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE3, &SHAPE4, - &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, - &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, - &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, - &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, - &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, - &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, - &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, - &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, - &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, - &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, - &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, - &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, - &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, - &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, - &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, - &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, - &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, - &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, - &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, - &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, - &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, - &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, - &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, - &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, - &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, - &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, + &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, + &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, + &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, + &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, + &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, + &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, + &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, + &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, + &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, + &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, + &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, + &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, + &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, + &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, + &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, + &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, + &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, + &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, + &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, + &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, + &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, + &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, + &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, + &SHAPE5, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE4, &SHAPE3, &SHAPE4, &SHAPE3, &SHAPE5, + &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE6, &SHAPE5, &SHAPE6, &SHAPE5, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE9, &SHAPE10, &SHAPE11, &SHAPE12, &SHAPE13, &SHAPE14, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE9, &SHAPE10, &SHAPE11, &SHAPE12, &SHAPE13, &SHAPE14, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE15, &SHAPE15, &SHAPE16, &SHAPE16, &SHAPE17, &SHAPE17, - &SHAPE18, &SHAPE18, &SHAPE19, &SHAPE19, &SHAPE20, &SHAPE20, &SHAPE21, &SHAPE21, &SHAPE22, - &SHAPE22, &SHAPE23, &SHAPE23, &SHAPE24, &SHAPE24, &SHAPE25, &SHAPE25, &SHAPE26, &SHAPE26, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE9, &SHAPE10, &SHAPE11, &SHAPE12, &SHAPE13, + &SHAPE14, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE9, &SHAPE10, &SHAPE11, &SHAPE12, &SHAPE13, &SHAPE14, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE15, &SHAPE15, &SHAPE16, &SHAPE16, + &SHAPE17, &SHAPE17, &SHAPE18, &SHAPE18, &SHAPE19, &SHAPE19, &SHAPE20, &SHAPE20, &SHAPE21, + &SHAPE21, &SHAPE22, &SHAPE22, &SHAPE23, &SHAPE23, &SHAPE24, &SHAPE24, &SHAPE25, &SHAPE25, + &SHAPE26, &SHAPE26, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, @@ -2012,8 +2017,6 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2064,20 +2067,21 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE53, &SHAPE53, &SHAPE54, &SHAPE54, - &SHAPE55, &SHAPE55, &SHAPE53, &SHAPE53, &SHAPE55, &SHAPE55, &SHAPE54, &SHAPE54, &SHAPE53, - &SHAPE53, &SHAPE56, &SHAPE56, &SHAPE57, &SHAPE57, &SHAPE53, &SHAPE53, &SHAPE57, &SHAPE57, - &SHAPE56, &SHAPE56, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, + &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, + &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, + &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, + &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, + &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, + &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, + &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, + &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, + &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE53, &SHAPE53, &SHAPE54, + &SHAPE54, &SHAPE55, &SHAPE55, &SHAPE53, &SHAPE53, &SHAPE55, &SHAPE55, &SHAPE54, &SHAPE54, + &SHAPE53, &SHAPE53, &SHAPE56, &SHAPE56, &SHAPE57, &SHAPE57, &SHAPE53, &SHAPE53, &SHAPE57, + &SHAPE57, &SHAPE56, &SHAPE56, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2205,11 +2209,11 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, &SHAPE62, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2232,36 +2236,41 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE67, &SHAPE67, - &SHAPE66, &SHAPE66, &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, - &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, - &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, - &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, - &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, - &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, - &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, - &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, - &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, - &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE29, &SHAPE29, + &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, + &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, + &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, + &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, + &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, + &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, + &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, + &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, + &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2308,6 +2317,13 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2333,52 +2349,81 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE69, &SHAPE69, - &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, - &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, - &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, - &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, - &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, + &SHAPE70, &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, + &SHAPE70, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, + &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE69, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE70, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, + &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, + &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE7, - &SHAPE58, &SHAPE59, &SHAPE8, &SHAPE60, &SHAPE13, &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE71, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE7, &SHAPE58, &SHAPE59, &SHAPE8, &SHAPE60, &SHAPE13, + &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, - &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE71, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, - &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, - &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, - &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, - &SHAPE1, &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE91, &SHAPE92, &SHAPE93, &SHAPE94, &SHAPE95, - &SHAPE96, &SHAPE97, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, + &SHAPE71, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, + &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, + &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, + &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, + &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE1, &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE91, &SHAPE92, &SHAPE93, &SHAPE94, &SHAPE95, &SHAPE96, &SHAPE97, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, - &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, + &SHAPE7, &SHAPE7, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, @@ -2399,28 +2444,13 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, + &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, @@ -2435,14 +2465,7 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE99, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, @@ -2462,17 +2485,16 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE100, &SHAPE101, &SHAPE100, - &SHAPE101, &SHAPE102, &SHAPE103, &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, - &SHAPE105, &SHAPE106, &SHAPE107, &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, - &SHAPE109, &SHAPE110, &SHAPE111, &SHAPE110, &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, - &SHAPE113, &SHAPE114, &SHAPE2, &SHAPE114, &SHAPE2, &SHAPE115, &SHAPE115, &SHAPE116, &SHAPE116, - &SHAPE117, &SHAPE117, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, &SHAPE102, &SHAPE103, - &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, - &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, - &SHAPE110, &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, &SHAPE114, &SHAPE2, - &SHAPE114, &SHAPE2, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, + &SHAPE102, &SHAPE103, &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, + &SHAPE106, &SHAPE107, &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, + &SHAPE110, &SHAPE111, &SHAPE110, &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, + &SHAPE114, &SHAPE2, &SHAPE114, &SHAPE2, &SHAPE115, &SHAPE115, &SHAPE116, &SHAPE116, &SHAPE117, + &SHAPE117, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, &SHAPE102, &SHAPE103, &SHAPE102, + &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, &SHAPE106, + &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, &SHAPE110, + &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, &SHAPE114, &SHAPE2, &SHAPE114, &SHAPE2, + &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2490,27 +2512,10 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, - &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, - &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, - &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, - &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, - &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, - &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, - &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, - &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, - &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, - &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, - &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, - &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, - &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, - &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, - &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, - &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, - &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, - &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, - &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, - &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, + &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, + &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, + &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, @@ -2519,11 +2524,7 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, - &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, &SHAPE1, &SHAPE119, - &SHAPE1, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, - &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, - &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, - &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE29, &SHAPE29, &SHAPE30, + &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, @@ -2532,22 +2533,44 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE13, - &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, - &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, - &SHAPE0, &SHAPE122, &SHAPE122, &SHAPE122, &SHAPE122, &SHAPE123, &SHAPE123, &SHAPE123, - &SHAPE123, &SHAPE1, &SHAPE72, &SHAPE1, &SHAPE1, &SHAPE124, &SHAPE125, &SHAPE126, &SHAPE127, - &SHAPE128, &SHAPE129, &SHAPE130, &SHAPE131, &SHAPE132, &SHAPE133, &SHAPE134, &SHAPE135, - &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, - &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, - &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, - &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, - &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, - &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, - &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, - &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, - &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, - &SHAPE1, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, + &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, &SHAPE1, &SHAPE119, &SHAPE1, &SHAPE74, + &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, + &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, + &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, + &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, + &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, + &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, + &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, + &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, + &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, + &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, + &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, + &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, + &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE13, &SHAPE120, + &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE120, &SHAPE121, + &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE121, &SHAPE0, + &SHAPE122, &SHAPE122, &SHAPE122, &SHAPE122, &SHAPE123, &SHAPE123, &SHAPE123, &SHAPE123, + &SHAPE1, &SHAPE72, &SHAPE1, &SHAPE1, &SHAPE124, &SHAPE125, &SHAPE126, &SHAPE127, &SHAPE128, + &SHAPE129, &SHAPE130, &SHAPE131, &SHAPE132, &SHAPE133, &SHAPE134, &SHAPE135, &SHAPE29, + &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, + &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, + &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, + &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, + &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, + &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, + &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, + &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, + &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, &SHAPE1, + &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE53, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2562,16 +2585,7 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, - &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, - &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, - &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, - &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, - &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, - &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, - &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, - &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, - &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, @@ -2589,75 +2603,30 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, - &SHAPE47, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, - &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, - &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, - &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, - &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE136, &SHAPE137, - &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, - &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, - &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, + &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, + &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, + &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, + &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, + &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, + &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, + &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, + &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, + &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, + &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, - &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, - &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, - &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, + &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, + &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, - &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, - &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, - &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, - &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, + &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, + &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, + &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, @@ -2671,8 +2640,62 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, + &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, + &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, + &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, + &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE136, &SHAPE137, &SHAPE137, + &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, + &SHAPE1, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -2692,75 +2715,81 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, - &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, &SHAPE171, &SHAPE171, &SHAPE172, - &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, + &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE169, &SHAPE170, &SHAPE170, + &SHAPE171, &SHAPE171, &SHAPE172, &SHAPE172, &SHAPE173, &SHAPE173, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, - &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE175, &SHAPE175, &SHAPE176, &SHAPE176, &SHAPE177, - &SHAPE177, &SHAPE178, &SHAPE178, &SHAPE179, &SHAPE179, &SHAPE180, &SHAPE180, &SHAPE179, - &SHAPE179, &SHAPE180, &SHAPE180, &SHAPE179, &SHAPE179, &SHAPE180, &SHAPE180, &SHAPE53, - &SHAPE53, &SHAPE54, &SHAPE54, &SHAPE55, &SHAPE55, &SHAPE53, &SHAPE53, &SHAPE55, &SHAPE55, - &SHAPE54, &SHAPE54, &SHAPE53, &SHAPE53, &SHAPE56, &SHAPE56, &SHAPE57, &SHAPE57, &SHAPE53, - &SHAPE53, &SHAPE57, &SHAPE57, &SHAPE56, &SHAPE56, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE174, &SHAPE175, &SHAPE175, + &SHAPE176, &SHAPE176, &SHAPE177, &SHAPE177, &SHAPE178, &SHAPE178, &SHAPE179, &SHAPE179, + &SHAPE180, &SHAPE180, &SHAPE179, &SHAPE179, &SHAPE180, &SHAPE180, &SHAPE179, &SHAPE179, + &SHAPE180, &SHAPE180, &SHAPE53, &SHAPE53, &SHAPE54, &SHAPE54, &SHAPE55, &SHAPE55, &SHAPE53, + &SHAPE53, &SHAPE55, &SHAPE55, &SHAPE54, &SHAPE54, &SHAPE53, &SHAPE53, &SHAPE56, &SHAPE56, + &SHAPE57, &SHAPE57, &SHAPE53, &SHAPE53, &SHAPE57, &SHAPE57, &SHAPE56, &SHAPE56, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE7, &SHAPE7, &SHAPE7, - &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, - &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, + &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE7, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, - &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE1, - &SHAPE1, &SHAPE181, &SHAPE182, &SHAPE183, &SHAPE184, &SHAPE185, &SHAPE181, &SHAPE182, - &SHAPE183, &SHAPE184, &SHAPE185, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, - &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, - &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, - &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, - &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, - &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, - &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, - &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, - &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, - &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, + &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, &SHAPE59, + &SHAPE59, &SHAPE59, &SHAPE1, &SHAPE1, &SHAPE181, &SHAPE182, &SHAPE183, &SHAPE184, &SHAPE185, + &SHAPE181, &SHAPE182, &SHAPE183, &SHAPE184, &SHAPE185, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, + &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, + &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, + &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, + &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, + &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, + &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, + &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, + &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, &SHAPE102, &SHAPE103, &SHAPE102, + &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, &SHAPE106, + &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, &SHAPE110, + &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, &SHAPE114, &SHAPE2, &SHAPE114, &SHAPE2, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, &SHAPE102, &SHAPE103, &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, &SHAPE110, &SHAPE111, @@ -2820,10 +2849,6 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, &SHAPE110, &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, &SHAPE114, &SHAPE2, - &SHAPE114, &SHAPE2, &SHAPE100, &SHAPE101, &SHAPE100, &SHAPE101, &SHAPE102, &SHAPE103, - &SHAPE102, &SHAPE103, &SHAPE104, &SHAPE105, &SHAPE104, &SHAPE105, &SHAPE106, &SHAPE107, - &SHAPE106, &SHAPE107, &SHAPE108, &SHAPE109, &SHAPE108, &SHAPE109, &SHAPE110, &SHAPE111, - &SHAPE110, &SHAPE111, &SHAPE112, &SHAPE113, &SHAPE112, &SHAPE113, &SHAPE114, &SHAPE2, &SHAPE114, &SHAPE2, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, @@ -2850,7 +2875,15 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, - &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, + &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, @@ -2966,6 +2999,9 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, + &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, @@ -2974,10 +3010,14 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, - &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, - &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE80, + &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, + &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, + &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, + &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, + &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, + &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, + &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, @@ -2989,42 +3029,42 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, - &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, - &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, - &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, - &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, - &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, + &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, - &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, - &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, - &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, - &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE74, &SHAPE75, + &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, + &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, + &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, + &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, + &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, + &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, + &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, + &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, + &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, + &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, + &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, + &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, + &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, + &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, + &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, - &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, - &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, - &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, - &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, - &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, - &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, - &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, - &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, - &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, - &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, - &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, - &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, - &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, - &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, - &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, - &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, + &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, @@ -3073,47 +3113,52 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE187, &SHAPE188, &SHAPE187, &SHAPE188, &SHAPE90, &SHAPE90, &SHAPE189, &SHAPE190, - &SHAPE191, &SHAPE192, &SHAPE193, &SHAPE194, &SHAPE195, &SHAPE196, &SHAPE197, &SHAPE198, - &SHAPE199, &SHAPE200, &SHAPE201, &SHAPE202, &SHAPE203, &SHAPE204, &SHAPE205, &SHAPE206, - &SHAPE207, &SHAPE208, &SHAPE209, &SHAPE210, &SHAPE211, &SHAPE212, &SHAPE213, &SHAPE214, - &SHAPE215, &SHAPE216, &SHAPE217, &SHAPE68, &SHAPE218, &SHAPE219, &SHAPE220, &SHAPE221, - &SHAPE222, &SHAPE223, &SHAPE224, &SHAPE225, &SHAPE226, &SHAPE227, &SHAPE228, &SHAPE229, - &SHAPE230, &SHAPE231, &SHAPE232, &SHAPE233, &SHAPE234, &SHAPE235, &SHAPE236, &SHAPE237, - &SHAPE238, &SHAPE239, &SHAPE240, &SHAPE241, &SHAPE242, &SHAPE243, &SHAPE244, &SHAPE245, - &SHAPE246, &SHAPE247, &SHAPE248, &SHAPE249, &SHAPE250, &SHAPE251, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE252, - &SHAPE252, &SHAPE0, &SHAPE253, &SHAPE0, &SHAPE253, &SHAPE0, &SHAPE253, &SHAPE0, &SHAPE253, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE62, &SHAPE0, &SHAPE1, &SHAPE1, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, + &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE187, &SHAPE188, &SHAPE187, &SHAPE188, + &SHAPE90, &SHAPE90, &SHAPE189, &SHAPE190, &SHAPE191, &SHAPE192, &SHAPE193, &SHAPE194, + &SHAPE195, &SHAPE196, &SHAPE197, &SHAPE198, &SHAPE199, &SHAPE200, &SHAPE201, &SHAPE202, + &SHAPE203, &SHAPE204, &SHAPE205, &SHAPE206, &SHAPE207, &SHAPE208, &SHAPE209, &SHAPE210, + &SHAPE211, &SHAPE212, &SHAPE213, &SHAPE214, &SHAPE215, &SHAPE216, &SHAPE217, &SHAPE68, + &SHAPE218, &SHAPE219, &SHAPE220, &SHAPE221, &SHAPE222, &SHAPE223, &SHAPE224, &SHAPE225, + &SHAPE226, &SHAPE227, &SHAPE228, &SHAPE229, &SHAPE230, &SHAPE231, &SHAPE232, &SHAPE233, + &SHAPE234, &SHAPE235, &SHAPE236, &SHAPE237, &SHAPE238, &SHAPE239, &SHAPE240, &SHAPE241, + &SHAPE242, &SHAPE243, &SHAPE244, &SHAPE245, &SHAPE246, &SHAPE247, &SHAPE248, &SHAPE249, + &SHAPE250, &SHAPE251, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, + &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, + &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, + &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, + &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, + &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, + &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, + &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, + &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, + &SHAPE47, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE252, &SHAPE252, &SHAPE0, &SHAPE253, &SHAPE0, + &SHAPE253, &SHAPE0, &SHAPE253, &SHAPE0, &SHAPE253, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE62, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, @@ -3133,14 +3178,14 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE1, &SHAPE255, &SHAPE255, &SHAPE255, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, - &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE257, &SHAPE257, &SHAPE257, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE255, &SHAPE255, &SHAPE255, + &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, &SHAPE256, + &SHAPE256, &SHAPE257, &SHAPE257, &SHAPE257, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, @@ -3151,45 +3196,11 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE258, &SHAPE258, &SHAPE259, &SHAPE259, &SHAPE260, &SHAPE260, &SHAPE261, &SHAPE261, - &SHAPE1, &SHAPE254, &SHAPE254, &SHAPE0, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, - &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE27, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, - &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, - &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, - &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, - &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, - &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, - &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, - &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, - &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, - &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, - &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, - &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, - &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, - &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, - &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, - &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, - &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, - &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, - &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, - &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, - &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, - &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, - &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, - &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, - &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, - &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, - &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, - &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, - &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, - &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, - &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, - &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, - &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, - &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, - &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, - &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE258, &SHAPE258, &SHAPE259, &SHAPE259, + &SHAPE260, &SHAPE260, &SHAPE261, &SHAPE261, &SHAPE1, &SHAPE254, &SHAPE254, &SHAPE0, &SHAPE116, + &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE116, + &SHAPE116, &SHAPE116, &SHAPE116, &SHAPE27, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, @@ -3278,15 +3289,91 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, - &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, - &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, + &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, + &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, + &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, + &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, + &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, + &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, + &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, + &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, + &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, + &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, + &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, + &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, + &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, + &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, + &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, + &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, + &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, + &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, + &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, + &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, + &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, + &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, + &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, + &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, + &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, + &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, + &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, + &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE136, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, + &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, + &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, + &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, + &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, + &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, + &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, + &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, + &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, + &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, + &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, + &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, + &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, + &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, + &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, + &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, @@ -3771,64 +3858,24 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE136, &SHAPE137, &SHAPE137, - &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, - &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, - &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, - &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, - &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, - &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, - &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, - &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, - &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, - &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, - &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, - &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, - &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, - &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, - &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, - &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, - &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, - &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, + &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE263, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE264, &SHAPE264, &SHAPE265, &SHAPE265, &SHAPE266, - &SHAPE267, &SHAPE268, &SHAPE269, &SHAPE270, &SHAPE270, &SHAPE271, &SHAPE271, &SHAPE272, + &SHAPE264, &SHAPE264, &SHAPE265, &SHAPE265, &SHAPE266, &SHAPE267, &SHAPE268, &SHAPE269, + &SHAPE270, &SHAPE270, &SHAPE271, &SHAPE271, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, - &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE1, - &SHAPE168, &SHAPE168, &SHAPE168, &SHAPE168, &SHAPE273, &SHAPE273, &SHAPE273, &SHAPE273, - &SHAPE274, &SHAPE274, &SHAPE274, &SHAPE274, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, - &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE276, &SHAPE276, &SHAPE277, &SHAPE277, - &SHAPE278, &SHAPE278, &SHAPE279, &SHAPE279, &SHAPE280, &SHAPE280, &SHAPE280, &SHAPE280, - &SHAPE281, &SHAPE281, &SHAPE281, &SHAPE281, &SHAPE282, &SHAPE282, &SHAPE283, &SHAPE283, - &SHAPE282, &SHAPE282, &SHAPE283, &SHAPE283, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, + &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE272, &SHAPE1, &SHAPE168, &SHAPE168, &SHAPE168, + &SHAPE168, &SHAPE273, &SHAPE273, &SHAPE273, &SHAPE273, &SHAPE274, &SHAPE274, &SHAPE274, + &SHAPE274, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, &SHAPE275, + &SHAPE275, &SHAPE276, &SHAPE276, &SHAPE277, &SHAPE277, &SHAPE278, &SHAPE278, &SHAPE279, + &SHAPE279, &SHAPE280, &SHAPE280, &SHAPE280, &SHAPE280, &SHAPE281, &SHAPE281, &SHAPE281, + &SHAPE281, &SHAPE282, &SHAPE282, &SHAPE283, &SHAPE283, &SHAPE282, &SHAPE282, &SHAPE283, + &SHAPE283, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, @@ -3836,152 +3883,201 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, - &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE167, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, - &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE167, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, - &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, - &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, - &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, - &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, - &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, - &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, - &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, - &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE0, &SHAPE0, &SHAPE80, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, + &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, + &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, + &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, + &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, &SHAPE89, &SHAPE74, &SHAPE75, &SHAPE74, &SHAPE75, + &SHAPE76, &SHAPE77, &SHAPE76, &SHAPE77, &SHAPE78, &SHAPE79, &SHAPE78, &SHAPE79, &SHAPE80, + &SHAPE81, &SHAPE80, &SHAPE81, &SHAPE82, &SHAPE83, &SHAPE82, &SHAPE83, &SHAPE84, &SHAPE85, + &SHAPE84, &SHAPE85, &SHAPE86, &SHAPE87, &SHAPE86, &SHAPE87, &SHAPE88, &SHAPE89, &SHAPE88, + &SHAPE89, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, - &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, - &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, - &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, - &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, - &SHAPE83, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, - &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, - &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, - &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, - &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, - &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, - &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, - &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, - &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, - &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, - &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, - &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, - &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, - &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, - &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, - &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, - &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, - &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, + &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE80, + &SHAPE80, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, + &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE0, &SHAPE0, &SHAPE83, &SHAPE83, &SHAPE29, &SHAPE29, + &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, + &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, + &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, + &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, + &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, + &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, + &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, + &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, + &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, + &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, + &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, + &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, + &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, + &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, + &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, + &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, + &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, + &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, - &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, - &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, + &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, - &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, &SHAPE284, + &SHAPE284, &SHAPE284, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE71, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, - &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, - &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, - &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, - &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE186, - &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE186, - &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE71, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE27, &SHAPE27, &SHAPE27, &SHAPE27, + &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, + &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, + &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, + &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, + &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, + &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, + &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, + &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, + &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, + &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, + &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, + &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, + &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, + &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, + &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, + &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, + &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, + &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, + &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, @@ -3990,634 +4086,106 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, - &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, - &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, - &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, - &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, - &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, - &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, - &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, - &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, - &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, - &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, - &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, - &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, - &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, - &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE136, - &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, - &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, - &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, - &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, - &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, - &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, - &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE287, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, - &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, - &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, - &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, - &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE1, &SHAPE1, &SHAPE289, - &SHAPE289, &SHAPE290, &SHAPE290, &SHAPE291, &SHAPE291, &SHAPE292, &SHAPE292, &SHAPE293, - &SHAPE293, &SHAPE294, &SHAPE294, &SHAPE295, &SHAPE295, &SHAPE296, &SHAPE296, &SHAPE297, - &SHAPE297, &SHAPE298, &SHAPE298, &SHAPE299, &SHAPE299, &SHAPE300, &SHAPE300, &SHAPE301, - &SHAPE301, &SHAPE302, &SHAPE302, &SHAPE303, &SHAPE303, &SHAPE304, &SHAPE304, &SHAPE305, - &SHAPE305, &SHAPE306, &SHAPE306, &SHAPE307, &SHAPE307, &SHAPE308, &SHAPE308, &SHAPE309, - &SHAPE309, &SHAPE310, &SHAPE310, &SHAPE311, &SHAPE311, &SHAPE312, &SHAPE312, &SHAPE1, - &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, - &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, - &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, - &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, - &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, - &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, - &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, - &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, - &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, - &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, - &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, - &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, - &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, - &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, - &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, - &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, - &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, - &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, - &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE0, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE1, &SHAPE1, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, - &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, - &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, - &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, - &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, - &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, - &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, - &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, - &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, - &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, - &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, - &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, - &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, - &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, - &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, - &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, - &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, - &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, - &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, - &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, - &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, - &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, - &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, - &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, - &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, - &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, - &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, - &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, - &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, - &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, - &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, - &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, - &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, - &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, - &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, - &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, - &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, - &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, - &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, - &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, - &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, - &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, - &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, - &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, - &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, - &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, - &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, - &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, - &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, - &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, - &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, - &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, - &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, - &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, - &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, - &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, - &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, - &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, - &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, - &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, - &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, - &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, - &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, - &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, - &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, - &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, - &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, - &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, - &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, - &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, - &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, - &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, - &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, - &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, - &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, - &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, - &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, - &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, - &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, - &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, - &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, - &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, - &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, - &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, - &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, - &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, - &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, - &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE188, - &SHAPE188, &SHAPE188, &SHAPE188, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE188, - &SHAPE188, &SHAPE188, &SHAPE188, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, - &SHAPE90, &SHAPE90, &SHAPE262, &SHAPE262, &SHAPE262, &SHAPE262, &SHAPE313, &SHAPE313, - &SHAPE314, &SHAPE314, &SHAPE63, &SHAPE63, &SHAPE63, &SHAPE63, &SHAPE68, &SHAPE68, &SHAPE68, - &SHAPE68, &SHAPE73, &SHAPE73, &SHAPE73, &SHAPE73, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE315, &SHAPE315, &SHAPE28, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE1, &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, - &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE316, - &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE316, &SHAPE316, - &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, - &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, - &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, - &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, - &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, - &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, - &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, - &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, - &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, - &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, - &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, - &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, - &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, - &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, - &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, - &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, - &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, - &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, - &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, - &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, - &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, - &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, - &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, - &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, - &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, - &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, - &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, - &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, - &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, - &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, - &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, - &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, - &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, - &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, - &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, - &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, - &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, - &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, - &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, - &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, - &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, - &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, - &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, - &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE136, &SHAPE137, &SHAPE137, + &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE118, &SHAPE285, &SHAPE285, + &SHAPE285, &SHAPE285, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE286, &SHAPE287, &SHAPE287, + &SHAPE287, &SHAPE287, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, + &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, + &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, + &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, + &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE288, &SHAPE1, &SHAPE1, &SHAPE289, &SHAPE289, &SHAPE290, + &SHAPE290, &SHAPE291, &SHAPE291, &SHAPE292, &SHAPE292, &SHAPE293, &SHAPE293, &SHAPE294, + &SHAPE294, &SHAPE295, &SHAPE295, &SHAPE296, &SHAPE296, &SHAPE297, &SHAPE297, &SHAPE298, + &SHAPE298, &SHAPE299, &SHAPE299, &SHAPE300, &SHAPE300, &SHAPE301, &SHAPE301, &SHAPE302, + &SHAPE302, &SHAPE303, &SHAPE303, &SHAPE304, &SHAPE304, &SHAPE305, &SHAPE305, &SHAPE306, + &SHAPE306, &SHAPE307, &SHAPE307, &SHAPE308, &SHAPE308, &SHAPE309, &SHAPE309, &SHAPE310, + &SHAPE310, &SHAPE311, &SHAPE311, &SHAPE312, &SHAPE312, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, + &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, + &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, + &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, + &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, + &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, + &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, + &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, + &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, + &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, @@ -4656,17 +4224,17 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, - &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, + &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, + &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, + &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, + &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, + &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, + &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, + &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, + &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, @@ -4706,17 +4274,17 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, - &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, - &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, - &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, - &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, - &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, - &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, - &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, - &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, - &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, - &SHAPE1, &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, + &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, + &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, + &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, + &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, + &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, + &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, + &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, + &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, + &SHAPE47, &SHAPE47, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, @@ -4756,14 +4324,493 @@ static SHAPES_MAP: [&LazyLock; 26644] = [ &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, - &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE27, &SHAPE27, &SHAPE1, &SHAPE1, - &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE72, - &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, - &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, + &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, + &SHAPE1, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, + &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, + &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, + &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, + &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, + &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, + &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, + &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, + &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, + &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, + &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, + &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, + &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, + &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, + &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, + &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, + &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, + &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, + &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, + &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, + &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, + &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, + &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, + &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, + &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, + &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, + &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, + &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, + &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, + &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, + &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, + &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, + &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, + &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, + &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, + &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, + &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, + &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, + &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, + &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, + &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, + &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, + &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, + &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, + &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, + &SHAPE47, &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, + &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, + &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, + &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, + &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, + &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, + &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, + &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, + &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, + &SHAPE47, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, + &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, + &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, + &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, + &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, + &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, + &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, + &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, + &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, + &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, + &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE186, + &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, &SHAPE1, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, + &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, + &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, + &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, + &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, + &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, + &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, + &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, + &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, + &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, + &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, + &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, + &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, &SHAPE66, + &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE65, + &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE65, + &SHAPE65, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE65, &SHAPE65, + &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE66, &SHAPE66, &SHAPE67, &SHAPE67, &SHAPE64, + &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE67, &SHAPE67, &SHAPE64, &SHAPE64, + &SHAPE65, &SHAPE65, &SHAPE64, &SHAPE64, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, + &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, + &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE65, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE98, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE98, &SHAPE98, &SHAPE98, + &SHAPE98, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE65, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE67, + &SHAPE67, &SHAPE67, &SHAPE67, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE66, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE66, &SHAPE66, &SHAPE66, + &SHAPE66, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, + &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE98, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE64, &SHAPE99, + &SHAPE99, &SHAPE99, &SHAPE99, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE188, &SHAPE188, &SHAPE188, + &SHAPE188, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE187, &SHAPE188, &SHAPE188, &SHAPE188, + &SHAPE188, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, &SHAPE90, + &SHAPE262, &SHAPE262, &SHAPE262, &SHAPE262, &SHAPE313, &SHAPE313, &SHAPE314, &SHAPE314, + &SHAPE63, &SHAPE63, &SHAPE63, &SHAPE63, &SHAPE68, &SHAPE68, &SHAPE68, &SHAPE68, &SHAPE73, + &SHAPE73, &SHAPE73, &SHAPE73, &SHAPE1, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE315, + &SHAPE315, &SHAPE28, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE1, &SHAPE316, + &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE316, &SHAPE316, + &SHAPE316, &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE316, &SHAPE316, &SHAPE316, + &SHAPE316, &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE316, &SHAPE316, &SHAPE316, &SHAPE316, + &SHAPE317, &SHAPE317, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, &SHAPE0, + &SHAPE1, &SHAPE61, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE29, &SHAPE29, &SHAPE30, &SHAPE30, + &SHAPE31, &SHAPE31, &SHAPE32, &SHAPE32, &SHAPE33, &SHAPE33, &SHAPE34, &SHAPE34, &SHAPE35, + &SHAPE35, &SHAPE36, &SHAPE36, &SHAPE37, &SHAPE37, &SHAPE38, &SHAPE38, &SHAPE39, &SHAPE39, + &SHAPE40, &SHAPE40, &SHAPE41, &SHAPE41, &SHAPE42, &SHAPE42, &SHAPE43, &SHAPE43, &SHAPE44, + &SHAPE44, &SHAPE45, &SHAPE45, &SHAPE46, &SHAPE46, &SHAPE47, &SHAPE47, &SHAPE48, &SHAPE48, + &SHAPE49, &SHAPE49, &SHAPE41, &SHAPE41, &SHAPE30, &SHAPE30, &SHAPE43, &SHAPE43, &SHAPE32, + &SHAPE32, &SHAPE50, &SHAPE50, &SHAPE46, &SHAPE46, &SHAPE35, &SHAPE35, &SHAPE48, &SHAPE48, + &SHAPE37, &SHAPE37, &SHAPE51, &SHAPE51, &SHAPE31, &SHAPE31, &SHAPE40, &SHAPE40, &SHAPE33, + &SHAPE33, &SHAPE42, &SHAPE42, &SHAPE52, &SHAPE52, &SHAPE36, &SHAPE36, &SHAPE45, &SHAPE45, + &SHAPE38, &SHAPE38, &SHAPE47, &SHAPE47, &SHAPE186, &SHAPE186, &SHAPE8, &SHAPE8, &SHAPE1, + &SHAPE1, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE136, &SHAPE137, &SHAPE137, &SHAPE0, &SHAPE138, + &SHAPE138, &SHAPE0, &SHAPE138, &SHAPE138, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, + &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, + &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE139, &SHAPE140, &SHAPE140, &SHAPE141, &SHAPE142, + &SHAPE142, &SHAPE141, &SHAPE142, &SHAPE142, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, + &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE143, &SHAPE144, &SHAPE144, &SHAPE145, &SHAPE146, + &SHAPE146, &SHAPE145, &SHAPE146, &SHAPE146, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, + &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, + &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE147, &SHAPE148, &SHAPE148, &SHAPE149, &SHAPE150, + &SHAPE150, &SHAPE149, &SHAPE150, &SHAPE150, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, + &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE151, &SHAPE152, &SHAPE152, &SHAPE153, &SHAPE154, + &SHAPE154, &SHAPE153, &SHAPE154, &SHAPE154, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, + &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, + &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE155, &SHAPE156, &SHAPE156, &SHAPE157, &SHAPE158, + &SHAPE158, &SHAPE157, &SHAPE158, &SHAPE158, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, + &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE159, &SHAPE160, &SHAPE160, &SHAPE161, &SHAPE162, + &SHAPE162, &SHAPE161, &SHAPE162, &SHAPE162, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, + &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, + &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE163, &SHAPE164, &SHAPE164, &SHAPE165, &SHAPE166, + &SHAPE166, &SHAPE165, &SHAPE166, &SHAPE166, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE27, &SHAPE27, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE0, &SHAPE1, &SHAPE72, &SHAPE72, + &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, + &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE72, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, + &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, &SHAPE1, ]; diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs index 3986dc47..7d7ddc5e 100644 --- a/azalea-physics/src/collision/mod.rs +++ b/azalea-physics/src/collision/mod.rs @@ -58,7 +58,7 @@ fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics) // let entity_collisions = world.get_entity_collisions(self, // entity_bounding_box.expand_towards(movement)); let entity_collisions = Vec::new(); - let collided_delta = if movement.length_sqr() == 0.0 { + let collided_delta = if movement.length_squared() == 0.0 { *movement } else { collide_bounding_box( @@ -109,12 +109,16 @@ fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics) entity_collisions.clone(), ) .add(directly_up_delta); - if target_movement.horizontal_distance_sqr() > step_to_delta.horizontal_distance_sqr() { + if target_movement.horizontal_distance_squared() + > step_to_delta.horizontal_distance_squared() + { step_to_delta = target_movement; } } - if step_to_delta.horizontal_distance_sqr() > collided_delta.horizontal_distance_sqr() { + if step_to_delta.horizontal_distance_squared() + > collided_delta.horizontal_distance_squared() + { return step_to_delta.add(collide_bounding_box( &Vec3 { x: 0., @@ -162,7 +166,7 @@ pub fn move_colliding( let collide_result = collide(movement, world, physics); - let move_distance = collide_result.length_sqr(); + let move_distance = collide_result.length_squared(); if move_distance > EPSILON { // TODO: fall damage diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs index fab8d8dc..3f584952 100755 --- a/azalea-physics/src/collision/shape.rs +++ b/azalea-physics/src/collision/shape.rs @@ -423,7 +423,7 @@ impl VoxelShape { return None; } let vector = to - from; - if vector.length_sqr() < EPSILON { + if vector.length_squared() < EPSILON { return None; } let right_after_start = from + &(vector * 0.0001); diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index 70260396..998fb300 100644 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -699,10 +699,10 @@ mod tests { let block_state = world_lock.write().chunks.set_block_state( &BlockPos { x: 0, y: 69, z: 0 }, azalea_block::blocks::CobblestoneWall { - east: azalea_block::properties::EastWall::Low, - north: azalea_block::properties::NorthWall::Low, - south: azalea_block::properties::SouthWall::Low, - west: azalea_block::properties::WestWall::Low, + east: azalea_block::properties::WallEast::Low, + north: azalea_block::properties::WallNorth::Low, + south: azalea_block::properties::WallSouth::Low, + west: azalea_block::properties::WallWest::Low, up: false, waterlogged: false, } @@ -761,10 +761,10 @@ mod tests { z: -8, }, azalea_block::blocks::CobblestoneWall { - east: azalea_block::properties::EastWall::Low, - north: azalea_block::properties::NorthWall::Low, - south: azalea_block::properties::SouthWall::Low, - west: azalea_block::properties::WestWall::Low, + east: azalea_block::properties::WallEast::Low, + north: azalea_block::properties::WallNorth::Low, + south: azalea_block::properties::WallSouth::Low, + west: azalea_block::properties::WallWest::Low, up: false, waterlogged: false, } diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml index 4ed5081b..6a24c5ff 100644 --- a/azalea-protocol/Cargo.toml +++ b/azalea-protocol/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-protocol" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-protocol" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-protocol/README.md b/azalea-protocol/README.md index 3f0ea40e..e1923c9e 100755 --- a/azalea-protocol/README.md +++ b/azalea-protocol/README.md @@ -21,6 +21,6 @@ Adding new packets is usually pretty easy, but you'll want to have Minecraft's d ### Implementing packets -You can manually implement reading and writing functionality for a packet by implementing McBufReadable and McBufWritable, but you can also have this automatically generated for a struct or enum by deriving McBuf. +You can manually implement reading and writing functionality for a packet by implementing AzaleaRead and AzaleaWrite, but you can also have this automatically generated for a struct or enum by deriving AzBuf. Look at other packets as an example. diff --git a/azalea-protocol/azalea-protocol-macros/Cargo.toml b/azalea-protocol/azalea-protocol-macros/Cargo.toml index 4bc8c360..5f1d5b6e 100644 --- a/azalea-protocol/azalea-protocol-macros/Cargo.toml +++ b/azalea-protocol/azalea-protocol-macros/Cargo.toml @@ -3,7 +3,7 @@ description = "Macros internally used in azalea-protocol." edition = "2021" license = "MIT" name = "azalea-protocol-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-protocol/azalea-protocol-macros" [lib] diff --git a/azalea-protocol/azalea-protocol-macros/src/lib.rs b/azalea-protocol/azalea-protocol-macros/src/lib.rs index 756d0d82..393f8de9 100755 --- a/azalea-protocol/azalea-protocol-macros/src/lib.rs +++ b/azalea-protocol/azalea-protocol-macros/src/lib.rs @@ -1,9 +1,9 @@ use proc_macro::TokenStream; use quote::quote; use syn::{ - braced, + bracketed, parse::{Parse, ParseStream, Result}, - parse_macro_input, DeriveInput, Ident, LitInt, Token, + parse_macro_input, DeriveInput, Ident, Token, }; fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> TokenStream { @@ -20,19 +20,22 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke let contents = quote! { impl #ident { - pub fn get(self) -> #state { - #state::#variant_name(self) - } - pub fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - azalea_buf::McBufWritable::write_into(self, buf) + azalea_buf::AzaleaWrite::azalea_write(self, buf) } pub fn read( buf: &mut std::io::Cursor<&[u8]>, ) -> Result<#state, azalea_buf::BufReadError> { - use azalea_buf::McBufReadable; - Ok(Self::read_from(buf)?.get()) + use azalea_buf::AzaleaRead; + Ok(crate::packets::Packet::into_variant(Self::azalea_read(buf)?)) + } + + } + + impl crate::packets::Packet<#state> for #ident { + fn into_variant(self) -> #state { + #state::#variant_name(self) } } }; @@ -41,121 +44,99 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke } #[proc_macro_derive(ServerboundGamePacket, attributes(var))] -pub fn derive_serverbound_game_packet(input: TokenStream) -> TokenStream { +pub fn derive_s_game_packet(input: TokenStream) -> TokenStream { as_packet_derive(input, quote! {crate::packets::game::ServerboundGamePacket}) } #[proc_macro_derive(ServerboundHandshakePacket, attributes(var))] -pub fn derive_serverbound_handshake_packet(input: TokenStream) -> TokenStream { +pub fn derive_s_handshake_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, - quote! {crate::packets::handshaking::ServerboundHandshakePacket}, + quote! {crate::packets::handshake::ServerboundHandshakePacket}, ) } #[proc_macro_derive(ServerboundLoginPacket, attributes(var))] -pub fn derive_serverbound_login_packet(input: TokenStream) -> TokenStream { +pub fn derive_s_login_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, quote! {crate::packets::login::ServerboundLoginPacket}, ) } #[proc_macro_derive(ServerboundStatusPacket, attributes(var))] -pub fn derive_serverbound_status_packet(input: TokenStream) -> TokenStream { +pub fn derive_s_status_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, quote! {crate::packets::status::ServerboundStatusPacket}, ) } -#[proc_macro_derive(ServerboundConfigurationPacket, attributes(var))] -pub fn derive_serverbound_configuration_packet(input: TokenStream) -> TokenStream { +#[proc_macro_derive(ServerboundConfigPacket, attributes(var))] +pub fn derive_s_config_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, - quote! {crate::packets::configuration::ServerboundConfigurationPacket}, + quote! {crate::packets::config::ServerboundConfigPacket}, ) } #[proc_macro_derive(ClientboundGamePacket, attributes(var))] -pub fn derive_clientbound_game_packet(input: TokenStream) -> TokenStream { +pub fn derive_c_game_packet(input: TokenStream) -> TokenStream { as_packet_derive(input, quote! {crate::packets::game::ClientboundGamePacket}) } #[proc_macro_derive(ClientboundHandshakePacket, attributes(var))] -pub fn derive_clientbound_handshake_packet(input: TokenStream) -> TokenStream { +pub fn derive_c_handshake_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, - quote! {crate::packets::handshaking::ClientboundHandshakePacket}, + quote! {crate::packets::handshake::ClientboundHandshakePacket}, ) } #[proc_macro_derive(ClientboundLoginPacket, attributes(var))] -pub fn derive_clientbound_login_packet(input: TokenStream) -> TokenStream { +pub fn derive_c_login_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, quote! {crate::packets::login::ClientboundLoginPacket}, ) } #[proc_macro_derive(ClientboundStatusPacket, attributes(var))] -pub fn derive_clientbound_status_packet(input: TokenStream) -> TokenStream { +pub fn derive_c_status_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, quote! {crate::packets::status::ClientboundStatusPacket}, ) } -#[proc_macro_derive(ClientboundConfigurationPacket, attributes(var))] -pub fn derive_clientbound_configuration_packet(input: TokenStream) -> TokenStream { +#[proc_macro_derive(ClientboundConfigPacket, attributes(var))] +pub fn derive_c_config_packet(input: TokenStream) -> TokenStream { as_packet_derive( input, - quote! {crate::packets::configuration::ClientboundConfigurationPacket}, + quote! {crate::packets::config::ClientboundConfigPacket}, ) } #[derive(Debug)] -struct PacketIdPair { - id: u32, - module: Ident, - name: Ident, -} -#[derive(Debug)] -struct PacketIdMap { - packets: Vec, +struct PacketList { + packets: Vec, } -impl Parse for PacketIdMap { +impl Parse for PacketList { fn parse(input: ParseStream) -> Result { let mut packets = vec![]; // example: - // 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, - - // 0x0e - while let Ok(packet_id) = input.parse::() { - let packet_id = packet_id.base10_parse::()?; - // : - input.parse::()?; - // clientbound_change_difficulty_packet - let module: Ident = input.parse()?; - // :: - input.parse::()?; - // ClientboundChangeDifficultyPacket - let name: Ident = input.parse()?; - - packets.push(PacketIdPair { - id: packet_id, - module, - name, - }); - + // change_difficulty, + // keep_alive, + while let Ok(packet_name) = input.parse::() { + packets.push(packet_name); if input.parse::().is_err() { break; } } - Ok(PacketIdMap { packets }) + Ok(PacketList { packets }) } } #[derive(Debug)] struct DeclareStatePackets { name: Ident, - serverbound: PacketIdMap, - clientbound: PacketIdMap, + clientbound: PacketList, + serverbound: PacketList, } impl Parse for DeclareStatePackets { @@ -163,31 +144,31 @@ impl Parse for DeclareStatePackets { let name = input.parse()?; input.parse::()?; - let serverbound_token: Ident = input.parse()?; - if serverbound_token != "Serverbound" { + let clientbound_token: Ident = input.parse()?; + if clientbound_token != "Clientbound" { return Err(syn::Error::new( - serverbound_token.span(), - "Expected `Serverbound`", + clientbound_token.span(), + "Expected `Clientbound`", )); } input.parse::]>()?; let content; - braced!(content in input); - let serverbound = content.parse()?; + bracketed!(content in input); + let clientbound = content.parse()?; input.parse::()?; - let clientbound_token: Ident = input.parse()?; - if clientbound_token != "Clientbound" { + let serverbound_token: Ident = input.parse()?; + if serverbound_token != "Serverbound" { return Err(syn::Error::new( - clientbound_token.span(), - "Expected `Clientbound`", + serverbound_token.span(), + "Expected `Serverbound`", )); } input.parse::]>()?; let content; - braced!(content in input); - let clientbound = content.parse()?; + bracketed!(content in input); + let serverbound = content.parse()?; Ok(DeclareStatePackets { name, @@ -200,92 +181,111 @@ impl Parse for DeclareStatePackets { pub fn declare_state_packets(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeclareStatePackets); - let serverbound_state_name = - Ident::new(&format!("Serverbound{}", input.name), input.name.span()); let clientbound_state_name = Ident::new(&format!("Clientbound{}", input.name), input.name.span()); + let serverbound_state_name = + Ident::new(&format!("Serverbound{}", input.name), input.name.span()); let state_name_litstr = syn::LitStr::new(&input.name.to_string(), input.name.span()); - let has_serverbound_packets = !input.serverbound.packets.is_empty(); let has_clientbound_packets = !input.clientbound.packets.is_empty(); + let has_serverbound_packets = !input.serverbound.packets.is_empty(); - let mut serverbound_enum_contents = quote!(); + let mut mod_and_use_statements_contents = quote!(); let mut clientbound_enum_contents = quote!(); - let mut serverbound_id_match_contents = quote!(); + let mut serverbound_enum_contents = quote!(); let mut clientbound_id_match_contents = quote!(); - let mut serverbound_write_match_contents = quote!(); + let mut serverbound_id_match_contents = quote!(); let mut clientbound_write_match_contents = quote!(); - let mut serverbound_read_match_contents = quote!(); + let mut serverbound_write_match_contents = quote!(); let mut clientbound_read_match_contents = quote!(); + let mut serverbound_read_match_contents = quote!(); - for PacketIdPair { id, module, name } in input.serverbound.packets { - let variant_name = variant_name_from(&name); + for (id, packet_name) in input.clientbound.packets.iter().enumerate() { + let id = id as u32; - let name_litstr = syn::LitStr::new(&name.to_string(), name.span()); - serverbound_enum_contents.extend(quote! { - #variant_name(#module::#name), + let struct_name = packet_name_to_struct_name(packet_name, "clientbound"); + let module_name = packet_name_to_module_name(packet_name, "clientbound"); + let variant_name = packet_name_to_variant_name(packet_name); + let packet_name_litstr = syn::LitStr::new(&packet_name.to_string(), packet_name.span()); + + mod_and_use_statements_contents.extend(quote! { + pub mod #module_name; + pub use #module_name::#struct_name; }); - serverbound_id_match_contents.extend(quote! { - #serverbound_state_name::#variant_name(_packet) => #id, + + clientbound_enum_contents.extend(quote! { + #variant_name(#module_name::#struct_name), }); - serverbound_write_match_contents.extend(quote! { - #serverbound_state_name::#variant_name(packet) => packet.write(buf), + clientbound_id_match_contents.extend(quote! { + #clientbound_state_name::#variant_name(_packet) => #id, }); - serverbound_read_match_contents.extend(quote! { + clientbound_write_match_contents.extend(quote! { + #clientbound_state_name::#variant_name(packet) => packet.write(buf), + }); + clientbound_read_match_contents.extend(quote! { #id => { - let data = #module::#name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse { + let data = #module_name::#struct_name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse { source: e, packet_id: #id, backtrace: Box::new(std::backtrace::Backtrace::capture()), - packet_name: #name_litstr.to_string(), + packet_name: #packet_name_litstr.to_string(), })?; #[cfg(debug_assertions)] { let mut leftover = Vec::new(); let _ = std::io::Read::read_to_end(buf, &mut leftover); if !leftover.is_empty() { - return Err(Box::new(crate::read::ReadPacketError::LeftoverData { packet_name: #name_litstr.to_string(), data: leftover })); + return Err( + Box::new( + crate::read::ReadPacketError::LeftoverData { + packet_name: #packet_name_litstr.to_string(), + data: leftover + } + ) + ); } } data }, }); } - for PacketIdPair { id, module, name } in input.clientbound.packets { - let name_litstr = syn::LitStr::new(&name.to_string(), name.span()); - let variant_name = variant_name_from(&name); + for (id, packet_name) in input.serverbound.packets.iter().enumerate() { + let id = id as u32; - clientbound_enum_contents.extend(quote! { - #variant_name(#module::#name), + let struct_name = packet_name_to_struct_name(packet_name, "serverbound"); + let module_name = packet_name_to_module_name(packet_name, "serverbound"); + let variant_name = packet_name_to_variant_name(packet_name); + let packet_name_litstr = syn::LitStr::new(&packet_name.to_string(), packet_name.span()); + + mod_and_use_statements_contents.extend(quote! { + pub mod #module_name; + pub use #module_name::#struct_name; }); - clientbound_id_match_contents.extend(quote! { - #clientbound_state_name::#variant_name(_packet) => #id, + + serverbound_enum_contents.extend(quote! { + #variant_name(#module_name::#struct_name), }); - clientbound_write_match_contents.extend(quote! { - #clientbound_state_name::#variant_name(packet) => packet.write(buf), + serverbound_id_match_contents.extend(quote! { + #serverbound_state_name::#variant_name(_packet) => #id, }); - clientbound_read_match_contents.extend(quote! { + serverbound_write_match_contents.extend(quote! { + #serverbound_state_name::#variant_name(packet) => packet.write(buf), + }); + serverbound_read_match_contents.extend(quote! { #id => { - let data = #module::#name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse { + let data = #module_name::#struct_name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse { source: e, packet_id: #id, backtrace: Box::new(std::backtrace::Backtrace::capture()), - packet_name: #name_litstr.to_string(), + packet_name: #packet_name_litstr.to_string(), })?; #[cfg(debug_assertions)] { let mut leftover = Vec::new(); let _ = std::io::Read::read_to_end(buf, &mut leftover); if !leftover.is_empty() { - return Err( - Box::new( - crate::read::ReadPacketError::LeftoverData { - packet_name: #name_litstr.to_string(), - data: leftover - } - ) - ); + return Err(Box::new(crate::read::ReadPacketError::LeftoverData { packet_name: #packet_name_litstr.to_string(), data: leftover })); } } data @@ -311,19 +311,21 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream { } let mut contents = quote! { + #mod_and_use_statements_contents + #[derive(Clone, Debug)] - pub enum #serverbound_state_name + pub enum #clientbound_state_name where - Self: Sized, + Self: Sized, { - #serverbound_enum_contents + #clientbound_enum_contents } #[derive(Clone, Debug)] - pub enum #clientbound_state_name + pub enum #serverbound_state_name where - Self: Sized, + Self: Sized, { - #clientbound_enum_contents + #serverbound_enum_contents } }; @@ -356,6 +358,13 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream { }) } } + + impl crate::packets::Packet<#serverbound_state_name> for #serverbound_state_name { + /// No-op, exists so you can pass a packet enum when a Packet<> is expected. + fn into_variant(self) -> #serverbound_state_name { + self + } + } }); contents.extend(quote! { @@ -400,8 +409,50 @@ fn variant_name_from(name: &syn::Ident) -> syn::Ident { } else if variant_name.starts_with("Serverbound") { variant_name = variant_name["Serverbound".len()..].to_string(); } - if variant_name.ends_with("Packet") { - variant_name = variant_name[..variant_name.len() - "Packet".len()].to_string(); - } syn::Ident::new(&variant_name, name.span()) } + +fn packet_name_to_struct_name(name: &syn::Ident, direction: &str) -> syn::Ident { + let struct_name_snake = format!("{direction}_{name}"); + let struct_name = to_camel_case(&struct_name_snake); + syn::Ident::new(&struct_name, name.span()) +} +fn packet_name_to_module_name(name: &syn::Ident, direction: &str) -> syn::Ident { + let module_name_snake = format!("{}_{name}", direction.chars().next().unwrap()); + let module_name = to_snake_case(&module_name_snake); + syn::Ident::new(&module_name, name.span()) +} +fn packet_name_to_variant_name(name: &syn::Ident) -> syn::Ident { + let variant_name = to_camel_case(&name.to_string()); + syn::Ident::new(&variant_name, name.span()) +} + +fn to_camel_case(snake_case: &str) -> String { + let mut camel_case = String::new(); + let mut capitalize_next = true; + for c in snake_case.chars() { + if c == '_' { + capitalize_next = true; + } else { + if capitalize_next { + camel_case.push(c.to_ascii_uppercase()); + } else { + camel_case.push(c); + } + capitalize_next = false; + } + } + camel_case +} +fn to_snake_case(camel_case: &str) -> String { + let mut snake_case = String::new(); + for c in camel_case.chars() { + if c.is_ascii_uppercase() { + snake_case.push('_'); + snake_case.push(c.to_ascii_lowercase()); + } else { + snake_case.push(c); + } + } + snake_case +} diff --git a/azalea-protocol/examples/handshake_proxy.rs b/azalea-protocol/examples/handshake_proxy.rs index 14e5115e..7ff7eaae 100644 --- a/azalea-protocol/examples/handshake_proxy.rs +++ b/azalea-protocol/examples/handshake_proxy.rs @@ -6,19 +6,17 @@ use std::{error::Error, sync::LazyLock}; use azalea_protocol::{ connect::Connection, packets::{ - handshaking::{ - client_intention_packet::ClientIntentionPacket, ClientboundHandshakePacket, + handshake::{ + s_intention::ServerboundIntention, ClientboundHandshakePacket, ServerboundHandshakePacket, }, - login::{serverbound_hello_packet::ServerboundHelloPacket, ServerboundLoginPacket}, + login::{s_hello::ServerboundHello, ServerboundLoginPacket}, status::{ - clientbound_pong_response_packet::ClientboundPongResponsePacket, - clientbound_status_response_packet::{ - ClientboundStatusResponsePacket, Players, Version, - }, + c_pong_response::ClientboundPongResponse, + c_status_response::{ClientboundStatusResponse, Players, Version}, ServerboundStatusPacket, }, - ClientIntention, PROTOCOL_VERSION, + ClientIntention, PROTOCOL_VERSION, VERSION_NAME, }, read::ReadPacketError, }; @@ -39,7 +37,7 @@ const PROXY_DESC: &str = "An Azalea Minecraft Proxy"; static PROXY_FAVICON: LazyLock> = LazyLock::new(|| None); static PROXY_VERSION: LazyLock = LazyLock::new(|| Version { - name: "1.19.3".to_string(), + name: VERSION_NAME.to_string(), protocol: PROTOCOL_VERSION, }); @@ -75,7 +73,7 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> { // the server or is going to join the game. let intent = match conn.read().await { Ok(packet) => match packet { - ServerboundHandshakePacket::ClientIntention(packet) => { + ServerboundHandshakePacket::Intention(packet) => { info!( "New connection: {0}, Version {1}, {2:?}", ip.ip(), @@ -101,21 +99,17 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> { match conn.read().await { Ok(p) => match p { ServerboundStatusPacket::StatusRequest(_) => { - conn.write( - ClientboundStatusResponsePacket { - description: PROXY_DESC.into(), - favicon: PROXY_FAVICON.clone(), - players: PROXY_PLAYERS.clone(), - version: PROXY_VERSION.clone(), - enforces_secure_chat: PROXY_SECURE_CHAT, - } - .get(), - ) + conn.write(ClientboundStatusResponse { + description: PROXY_DESC.into(), + favicon: PROXY_FAVICON.clone(), + players: PROXY_PLAYERS.clone(), + version: PROXY_VERSION.clone(), + enforces_secure_chat: PROXY_SECURE_CHAT, + }) .await?; } ServerboundStatusPacket::PingRequest(p) => { - conn.write(ClientboundPongResponsePacket { time: p.time }.get()) - .await?; + conn.write(ClientboundPongResponse { time: p.time }).await?; break; } }, @@ -179,8 +173,8 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> { async fn transfer( mut inbound: TcpStream, - intent: ClientIntentionPacket, - hello: ServerboundHelloPacket, + intent: ServerboundIntention, + hello: ServerboundHello, ) -> Result<(), Box> { let outbound = TcpStream::connect(PROXY_ADDR).await?; let name = hello.name.clone(); @@ -190,10 +184,10 @@ async fn transfer( // received earlier to the proxy target let mut outbound_conn: Connection = Connection::wrap(outbound); - outbound_conn.write(intent.get()).await?; + outbound_conn.write(intent).await?; let mut outbound_conn = outbound_conn.login(); - outbound_conn.write(hello.get()).await?; + outbound_conn.write(hello).await?; let mut outbound = outbound_conn.unwrap()?; diff --git a/azalea-protocol/src/common/client_information.rs b/azalea-protocol/src/common/client_information.rs new file mode 100644 index 00000000..6f5e05e2 --- /dev/null +++ b/azalea-protocol/src/common/client_information.rs @@ -0,0 +1,187 @@ +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite}; +use azalea_core::bitset::FixedBitSet; +use bevy_ecs::component::Component; + +/// A component that contains some of the "settings" for this client that are +/// sent to the server, such as render distance. This is only present on local +/// players. +#[derive(Clone, Debug, AzBuf, PartialEq, Eq, Component)] +pub struct ClientInformation { + /// The locale of the client. + pub language: String, + /// The view distance of the client in chunks, same as the render distance + /// in-game. + pub view_distance: u8, + /// The types of chat messages the client wants to receive. Note that many + /// servers ignore this. + pub chat_visibility: ChatVisibility, + /// Whether the messages sent from the server should have colors. Note that + /// many servers ignore this and always send colored messages. + pub chat_colors: bool, + pub model_customization: ModelCustomization, + pub main_hand: HumanoidArm, + pub text_filtering_enabled: bool, + /// Whether the client should show up as "Anonymous Player" in the server + /// list. + pub allows_listing: bool, + pub particle_status: ParticleStatus, +} + +impl Default for ClientInformation { + fn default() -> Self { + Self { + language: "en_us".to_string(), + view_distance: 8, + chat_visibility: ChatVisibility::default(), + chat_colors: true, + model_customization: ModelCustomization::default(), + main_hand: HumanoidArm::Right, + text_filtering_enabled: false, + allows_listing: false, + particle_status: ParticleStatus::default(), + } + } +} + +#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum ChatVisibility { + /// All chat messages should be sent to the client. + #[default] + Full = 0, + /// Chat messages from other players should be not sent to the client, only + /// messages from the server like "Player joined the game" should be sent. + System = 1, + /// No chat messages should be sent to the client. + Hidden = 2, +} + +#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum HumanoidArm { + Left = 0, + #[default] + Right = 1, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct ModelCustomization { + pub cape: bool, + pub jacket: bool, + pub left_sleeve: bool, + pub right_sleeve: bool, + pub left_pants: bool, + pub right_pants: bool, + pub hat: bool, +} + +#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum ParticleStatus { + #[default] + All, + Decreased, + Minimal, +} + +impl Default for ModelCustomization { + fn default() -> Self { + Self { + cape: true, + jacket: true, + left_sleeve: true, + right_sleeve: true, + left_pants: true, + right_pants: true, + hat: true, + } + } +} + +impl AzaleaRead for ModelCustomization { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<7>::azalea_read(buf)?; + Ok(Self { + cape: set.index(0), + jacket: set.index(1), + left_sleeve: set.index(2), + right_sleeve: set.index(3), + left_pants: set.index(4), + right_pants: set.index(5), + hat: set.index(6), + }) + } +} + +impl AzaleaWrite for ModelCustomization { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<7>::new(); + if self.cape { + set.set(0); + } + if self.jacket { + set.set(1); + } + if self.left_sleeve { + set.set(2); + } + if self.right_sleeve { + set.set(3); + } + if self.left_pants { + set.set(4); + } + if self.right_pants { + set.set(5); + } + if self.hat { + set.set(6); + } + set.azalea_write(buf) + } +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::{AzaleaRead, AzaleaWrite}; + + use super::*; + + #[test] + fn test_client_information() { + { + let data = ClientInformation::default(); + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + + let read_data = ClientInformation::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(read_data, data); + } + + let data = ClientInformation { + language: "en_gb".to_string(), + view_distance: 24, + chat_visibility: ChatVisibility::Hidden, + chat_colors: false, + model_customization: ModelCustomization { + cape: false, + jacket: false, + left_sleeve: true, + right_sleeve: false, + left_pants: true, + right_pants: false, + hat: true, + }, + main_hand: HumanoidArm::Left, + text_filtering_enabled: true, + allows_listing: true, + particle_status: ParticleStatus::Decreased, + }; + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + + let read_data = ClientInformation::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(read_data, data); + } +} diff --git a/azalea-protocol/src/common/mod.rs b/azalea-protocol/src/common/mod.rs new file mode 100644 index 00000000..da535b48 --- /dev/null +++ b/azalea-protocol/src/common/mod.rs @@ -0,0 +1,4 @@ +//! Some serializable data types that are used by several packets. + +pub mod client_information; +pub mod server_links; diff --git a/azalea-protocol/src/common/server_links.rs b/azalea-protocol/src/common/server_links.rs new file mode 100644 index 00000000..4aed98f3 --- /dev/null +++ b/azalea-protocol/src/common/server_links.rs @@ -0,0 +1,28 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; + +#[derive(Clone, Debug, AzBuf)] +pub struct ServerLinkEntry { + pub kind: ServerLinkKind, + pub link: String, +} + +#[derive(Clone, Debug, AzBuf)] +pub enum ServerLinkKind { + Known(KnownLinkKind), + Component(FormattedText), +} + +#[derive(Clone, Copy, Debug, AzBuf)] +pub enum KnownLinkKind { + BugReport, + CommunityGuidelines, + Support, + Status, + Feedback, + Community, + Website, + Forums, + News, + Announcements, +} diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs index 0a449bfd..f64d9eb8 100755 --- a/azalea-protocol/src/connect.rs +++ b/azalea-protocol/src/connect.rs @@ -16,12 +16,10 @@ use tokio::net::TcpStream; use tracing::{error, info}; use uuid::Uuid; -use crate::packets::configuration::{ - ClientboundConfigurationPacket, ServerboundConfigurationPacket, -}; +use crate::packets::config::{ClientboundConfigPacket, ServerboundConfigPacket}; use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket}; -use crate::packets::handshaking::{ClientboundHandshakePacket, ServerboundHandshakePacket}; -use crate::packets::login::clientbound_hello_packet::ClientboundHelloPacket; +use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket}; +use crate::packets::login::c_hello::ClientboundHello; use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket}; use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket}; use crate::packets::ProtocolPacket; @@ -66,10 +64,10 @@ pub struct WriteConnection { /// ClientIntention, PROTOCOL_VERSION, /// login::{ /// ClientboundLoginPacket, -/// serverbound_hello_packet::ServerboundHelloPacket, -/// serverbound_key_packet::ServerboundKeyPacket +/// ServerboundHello, +/// ServerboundKey /// }, -/// handshaking::client_intention_packet::ClientIntentionPacket +/// handshake::ServerboundIntention /// } /// }; /// @@ -79,28 +77,20 @@ pub struct WriteConnection { /// let mut conn = Connection::new(&resolved_address).await?; /// /// // handshake -/// conn.write( -/// ClientIntentionPacket { -/// protocol_version: PROTOCOL_VERSION, -/// hostname: resolved_address.ip().to_string(), -/// port: resolved_address.port(), -/// intention: ClientIntention::Login, -/// } -/// .get(), -/// ) -/// .await?; +/// conn.write(ServerboundIntention { +/// protocol_version: PROTOCOL_VERSION, +/// hostname: resolved_address.ip().to_string(), +/// port: resolved_address.port(), +/// intention: ClientIntention::Login, +/// }).await?; /// /// let mut conn = conn.login(); /// /// // login -/// conn.write( -/// ServerboundHelloPacket { -/// name: "bot".to_string(), -/// profile_id: uuid::Uuid::nil(), -/// } -/// .get(), -/// ) -/// .await?; +/// conn.write(ServerboundHello { +/// name: "bot".to_string(), +/// profile_id: uuid::Uuid::nil(), +/// }).await?; /// /// let (conn, game_profile) = loop { /// let packet = conn.read().await?; @@ -108,14 +98,10 @@ pub struct WriteConnection { /// ClientboundLoginPacket::Hello(p) => { /// let e = azalea_crypto::encrypt(&p.public_key, &p.challenge).unwrap(); /// -/// conn.write( -/// ServerboundKeyPacket { -/// key_bytes: e.encrypted_public_key, -/// encrypted_challenge: e.encrypted_challenge, -/// } -/// .get(), -/// ) -/// .await?; +/// conn.write(ServerboundKey { +/// key_bytes: e.encrypted_public_key, +/// encrypted_challenge: e.encrypted_challenge, +/// }).await?; /// conn.set_encryption_key(e.secret_key); /// } /// ClientboundLoginPacket::LoginCompression(p) => { @@ -243,7 +229,8 @@ where } /// Write a packet to the other side of the connection. - pub async fn write(&mut self, packet: W) -> std::io::Result<()> { + pub async fn write(&mut self, packet: impl crate::packets::Packet) -> std::io::Result<()> { + let packet = packet.into_variant(); self.writer.write(packet).await } @@ -368,9 +355,7 @@ impl Connection { /// Change our state from login to configuration. This is the state where /// the server sends us the registries and resource pack and stuff. #[must_use] - pub fn configuration( - self, - ) -> Connection { + pub fn configuration(self) -> Connection { Connection::from(self) } @@ -385,7 +370,7 @@ impl Connection { /// use azalea_protocol::connect::Connection; /// use azalea_protocol::packets::login::{ /// ClientboundLoginPacket, - /// serverbound_key_packet::ServerboundKeyPacket + /// ServerboundKey /// }; /// use uuid::Uuid; /// # use azalea_protocol::ServerAddress; @@ -414,12 +399,10 @@ impl Connection { /// e.secret_key, /// &p /// ).await?; - /// conn.write( - /// ServerboundKeyPacket { - /// key_bytes: e.encrypted_public_key, - /// encrypted_challenge: e.encrypted_challenge, - /// }.get() - /// ).await?; + /// conn.write(ServerboundKey { + /// key_bytes: e.encrypted_public_key, + /// encrypted_challenge: e.encrypted_challenge, + /// }).await?; /// conn.set_encryption_key(e.secret_key); /// } /// _ => {} @@ -432,7 +415,7 @@ impl Connection { access_token: &str, uuid: &Uuid, private_key: [u8; 16], - packet: &ClientboundHelloPacket, + packet: &ClientboundHello, ) -> Result<(), ClientSessionServerError> { azalea_auth::sessionserver::join( access_token, @@ -506,14 +489,12 @@ impl Connection { /// Change our state back to configuration. #[must_use] - pub fn configuration( - self, - ) -> Connection { + pub fn configuration(self) -> Connection { Connection::from(self) } } -impl Connection { +impl Connection { /// Change our state from configuration to game. This is the state that's /// used when the client is actually in the world. #[must_use] @@ -522,7 +503,7 @@ impl Connection } } -impl Connection { +impl Connection { /// Change our state from configuration to game. This is the state that's /// used when the client is actually in the world. #[must_use] @@ -534,9 +515,7 @@ impl Connection impl Connection { /// Change our state back to configuration. #[must_use] - pub fn configuration( - self, - ) -> Connection { + pub fn configuration(self) -> Connection { Connection::from(self) } } diff --git a/azalea-protocol/src/lib.rs b/azalea-protocol/src/lib.rs index 1bbb80d4..fb271433 100644 --- a/azalea-protocol/src/lib.rs +++ b/azalea-protocol/src/lib.rs @@ -14,6 +14,7 @@ use std::{fmt::Display, net::SocketAddr, str::FromStr}; +pub mod common; #[cfg(feature = "connecting")] pub mod connect; #[cfg(feature = "packets")] @@ -108,8 +109,9 @@ mod tests { use crate::{ packets::{ - game::serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket}, - login::{serverbound_hello_packet::ServerboundHelloPacket, ServerboundLoginPacket}, + game::s_chat::{LastSeenMessagesUpdate, ServerboundChat}, + login::{s_hello::ServerboundHello, ServerboundLoginPacket}, + Packet, }, read::{compression_decoder, read_packet}, write::{compression_encoder, serialize_packet, write_packet}, @@ -117,13 +119,12 @@ mod tests { #[tokio::test] async fn test_hello_packet() { - let packet = ServerboundHelloPacket { + let packet = ServerboundHello { name: "test".to_string(), profile_id: Uuid::nil(), - } - .get(); + }; let mut stream = Vec::new(); - write_packet(&packet, &mut stream, None, &mut None) + write_packet(&packet.into_variant(), &mut stream, None, &mut None) .await .unwrap(); @@ -141,11 +142,11 @@ mod tests { #[tokio::test] async fn test_double_hello_packet() { - let packet = ServerboundHelloPacket { + let packet = ServerboundHello { name: "test".to_string(), profile_id: Uuid::nil(), } - .get(); + .into_variant(); let mut stream = Vec::new(); write_packet(&packet, &mut stream, None, &mut None) .await @@ -170,14 +171,14 @@ mod tests { let compression_threshold = 256; let buf = serialize_packet( - &ServerboundChatPacket { + &ServerboundChat { message: "a".repeat(256), timestamp: 0, salt: 0, signature: None, last_seen_messages: LastSeenMessagesUpdate::default(), } - .get(), + .into_variant(), ) .unwrap(); diff --git a/azalea-protocol/src/packets/common.rs b/azalea-protocol/src/packets/common.rs index 173e15fc..fc78cd7a 100644 --- a/azalea-protocol/src/packets/common.rs +++ b/azalea-protocol/src/packets/common.rs @@ -1,11 +1,11 @@ -use azalea_buf::McBuf; +use azalea_buf::AzBuf; use azalea_core::{ game_type::{GameMode, OptionalGameType}, position::GlobalPos, resource_location::ResourceLocation, }; -#[derive(Clone, Debug, McBuf)] +#[derive(Clone, Debug, AzBuf)] pub struct CommonPlayerSpawnInfo { pub dimension_type: azalea_registry::DimensionType, pub dimension: ResourceLocation, diff --git a/azalea-protocol/src/packets/config/c_cookie_request.rs b/azalea-protocol/src/packets/config/c_cookie_request.rs new file mode 100644 index 00000000..4c57718d --- /dev/null +++ b/azalea-protocol/src/packets/config/c_cookie_request.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundCookieRequest { + pub key: ResourceLocation, +} diff --git a/azalea-protocol/src/packets/config/c_custom_payload.rs b/azalea-protocol/src/packets/config/c_custom_payload.rs new file mode 100644 index 00000000..3432ac3a --- /dev/null +++ b/azalea-protocol/src/packets/config/c_custom_payload.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_buf::UnsizedByteArray; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundCustomPayload { + pub identifier: ResourceLocation, + pub data: UnsizedByteArray, +} diff --git a/azalea-protocol/src/packets/config/c_custom_report_details.rs b/azalea-protocol/src/packets/config/c_custom_report_details.rs new file mode 100644 index 00000000..5fa375d0 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_custom_report_details.rs @@ -0,0 +1,9 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundCustomReportDetails { + pub details: HashMap, +} diff --git a/azalea-protocol/src/packets/config/c_disconnect.rs b/azalea-protocol/src/packets/config/c_disconnect.rs new file mode 100644 index 00000000..b59b318d --- /dev/null +++ b/azalea-protocol/src/packets/config/c_disconnect.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundDisconnect { + pub reason: FormattedText, +} diff --git a/azalea-protocol/src/packets/config/c_finish_configuration.rs b/azalea-protocol/src/packets/config/c_finish_configuration.rs new file mode 100644 index 00000000..e3f3e5a5 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_finish_configuration.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundFinishConfiguration {} diff --git a/azalea-protocol/src/packets/config/c_keep_alive.rs b/azalea-protocol/src/packets/config/c_keep_alive.rs new file mode 100644 index 00000000..f0310c34 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_keep_alive.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundKeepAlive { + pub id: u64, +} diff --git a/azalea-protocol/src/packets/config/c_ping.rs b/azalea-protocol/src/packets/config/c_ping.rs new file mode 100644 index 00000000..35b5c39c --- /dev/null +++ b/azalea-protocol/src/packets/config/c_ping.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundPing { + pub id: u32, +} diff --git a/azalea-protocol/src/packets/config/c_registry_data.rs b/azalea-protocol/src/packets/config/c_registry_data.rs new file mode 100644 index 00000000..185de4c3 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_registry_data.rs @@ -0,0 +1,12 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; +use simdnbt::owned::NbtCompound; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundRegistryData { + pub registry_id: ResourceLocation, + pub entries: HashMap>, +} diff --git a/azalea-protocol/src/packets/config/c_reset_chat.rs b/azalea-protocol/src/packets/config/c_reset_chat.rs new file mode 100644 index 00000000..273cb0fd --- /dev/null +++ b/azalea-protocol/src/packets/config/c_reset_chat.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundResetChat; diff --git a/azalea-protocol/src/packets/config/c_resource_pack.rs b/azalea-protocol/src/packets/config/c_resource_pack.rs new file mode 100644 index 00000000..63a59b5b --- /dev/null +++ b/azalea-protocol/src/packets/config/c_resource_pack.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundResourcePack { + pub url: String, + pub hash: String, + pub required: bool, + pub prompt: Option, +} diff --git a/azalea-protocol/src/packets/config/c_resource_pack_pop.rs b/azalea-protocol/src/packets/config/c_resource_pack_pop.rs new file mode 100644 index 00000000..f949a726 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_resource_pack_pop.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundResourcePackPop { + pub id: Option, +} diff --git a/azalea-protocol/src/packets/config/c_resource_pack_push.rs b/azalea-protocol/src/packets/config/c_resource_pack_push.rs new file mode 100644 index 00000000..6be5c709 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_resource_pack_push.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundConfigPacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundResourcePackPush { + pub id: Uuid, + pub url: String, + pub hash: String, + pub required: bool, + pub prompt: Option, +} diff --git a/azalea-protocol/src/packets/config/c_select_known_packs.rs b/azalea-protocol/src/packets/config/c_select_known_packs.rs new file mode 100644 index 00000000..6a4f76db --- /dev/null +++ b/azalea-protocol/src/packets/config/c_select_known_packs.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +use super::s_select_known_packs::KnownPack; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundSelectKnownPacks { + pub known_packs: Vec, +} diff --git a/azalea-protocol/src/packets/config/c_server_links.rs b/azalea-protocol/src/packets/config/c_server_links.rs new file mode 100644 index 00000000..3420e592 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_server_links.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +use crate::common::server_links::ServerLinkEntry; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundServerLinks { + pub links: Vec, +} diff --git a/azalea-protocol/src/packets/config/c_store_cookie.rs b/azalea-protocol/src/packets/config/c_store_cookie.rs new file mode 100644 index 00000000..c52211ea --- /dev/null +++ b/azalea-protocol/src/packets/config/c_store_cookie.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundStoreCookie { + pub key: ResourceLocation, + pub payload: Vec, +} diff --git a/azalea-protocol/src/packets/config/c_transfer.rs b/azalea-protocol/src/packets/config/c_transfer.rs new file mode 100644 index 00000000..332421d8 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_transfer.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundTransfer { + pub host: String, + #[var] + pub port: u32, +} diff --git a/azalea-protocol/src/packets/config/c_update_enabled_features.rs b/azalea-protocol/src/packets/config/c_update_enabled_features.rs new file mode 100644 index 00000000..4529c757 --- /dev/null +++ b/azalea-protocol/src/packets/config/c_update_enabled_features.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundUpdateEnabledFeatures { + pub features: Vec, +} diff --git a/azalea-protocol/src/packets/config/c_update_tags.rs b/azalea-protocol/src/packets/config/c_update_tags.rs new file mode 100644 index 00000000..678a5ccf --- /dev/null +++ b/azalea-protocol/src/packets/config/c_update_tags.rs @@ -0,0 +1,74 @@ +use std::io::Cursor; +use std::ops::Deref; +use std::{collections::HashMap, io::Write}; + +use azalea_buf::{AzBuf, AzaleaReadVar, AzaleaWriteVar, BufReadError}; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)] +pub struct ClientboundUpdateTags { + pub tags: TagMap, +} + +#[derive(Clone, Debug)] +pub struct Tags { + pub name: ResourceLocation, + pub elements: Vec, +} + +#[derive(Clone, Debug)] +pub struct TagMap(pub HashMap>); + +impl AzaleaRead for TagMap { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let length = u32::azalea_read_var(buf)? as usize; + let mut data = HashMap::with_capacity(length); + for _ in 0..length { + let tag_type = ResourceLocation::azalea_read(buf)?; + let tags_count = i32::azalea_read_var(buf)? as usize; + let mut tags_vec = Vec::with_capacity(tags_count); + for _ in 0..tags_count { + let tags = Tags::azalea_read(buf)?; + tags_vec.push(tags); + } + data.insert(tag_type, tags_vec); + } + Ok(TagMap(data)) + } +} + +impl AzaleaWrite for TagMap { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.len() as u32).azalea_write_var(buf)?; + for (k, v) in &self.0 { + k.azalea_write(buf)?; + v.azalea_write(buf)?; + } + Ok(()) + } +} +impl AzaleaRead for Tags { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let name = ResourceLocation::azalea_read(buf)?; + let elements = Vec::::azalea_read_var(buf)?; + Ok(Tags { name, elements }) + } +} + +impl AzaleaWrite for Tags { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.name.azalea_write(buf)?; + self.elements.azalea_write_var(buf)?; + Ok(()) + } +} + +impl Deref for TagMap { + type Target = HashMap>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/azalea-protocol/src/packets/config/mod.rs b/azalea-protocol/src/packets/config/mod.rs new file mode 100755 index 00000000..4eda0f03 --- /dev/null +++ b/azalea-protocol/src/packets/config/mod.rs @@ -0,0 +1,36 @@ +// NOTE: This file is generated automatically by codegen/packet.py. +// Don't edit it directly! + +use azalea_protocol_macros::declare_state_packets; + +declare_state_packets!(ConfigPacket, + Clientbound => [ + cookie_request, + custom_payload, + disconnect, + finish_configuration, + keep_alive, + ping, + reset_chat, + registry_data, + resource_pack_pop, + resource_pack_push, + store_cookie, + transfer, + update_enabled_features, + update_tags, + select_known_packs, + custom_report_details, + server_links, + ], + Serverbound => [ + client_information, + cookie_response, + custom_payload, + finish_configuration, + keep_alive, + pong, + resource_pack, + select_known_packs, + ] +); diff --git a/azalea-protocol/src/packets/config/s_client_information.rs b/azalea-protocol/src/packets/config/s_client_information.rs new file mode 100644 index 00000000..d58ce502 --- /dev/null +++ b/azalea-protocol/src/packets/config/s_client_information.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; + +use crate::common::client_information::ClientInformation; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket, PartialEq, Eq)] +pub struct ServerboundClientInformation { + pub information: ClientInformation, +} diff --git a/azalea-protocol/src/packets/config/s_cookie_response.rs b/azalea-protocol/src/packets/config/s_cookie_response.rs new file mode 100644 index 00000000..e932352f --- /dev/null +++ b/azalea-protocol/src/packets/config/s_cookie_response.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundCookieResponse { + pub key: ResourceLocation, + pub payload: Option>, +} diff --git a/azalea-protocol/src/packets/config/s_custom_payload.rs b/azalea-protocol/src/packets/config/s_custom_payload.rs new file mode 100644 index 00000000..f480985d --- /dev/null +++ b/azalea-protocol/src/packets/config/s_custom_payload.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_buf::UnsizedByteArray; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundCustomPayload { + pub identifier: ResourceLocation, + pub data: UnsizedByteArray, +} diff --git a/azalea-protocol/src/packets/config/s_finish_configuration.rs b/azalea-protocol/src/packets/config/s_finish_configuration.rs new file mode 100644 index 00000000..a4d94fb1 --- /dev/null +++ b/azalea-protocol/src/packets/config/s_finish_configuration.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundFinishConfiguration {} diff --git a/azalea-protocol/src/packets/config/s_keep_alive.rs b/azalea-protocol/src/packets/config/s_keep_alive.rs new file mode 100644 index 00000000..1986a4eb --- /dev/null +++ b/azalea-protocol/src/packets/config/s_keep_alive.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundKeepAlive { + pub id: u64, +} diff --git a/azalea-protocol/src/packets/config/s_pong.rs b/azalea-protocol/src/packets/config/s_pong.rs new file mode 100644 index 00000000..50c012dd --- /dev/null +++ b/azalea-protocol/src/packets/config/s_pong.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundPong { + pub id: u32, +} diff --git a/azalea-protocol/src/packets/config/s_resource_pack.rs b/azalea-protocol/src/packets/config/s_resource_pack.rs new file mode 100644 index 00000000..0822c723 --- /dev/null +++ b/azalea-protocol/src/packets/config/s_resource_pack.rs @@ -0,0 +1,20 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundResourcePack { + pub id: Uuid, + pub action: Action, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + SuccessfullyLoaded = 0, + Declined = 1, + FailedDownload = 2, + Accepted = 3, + InvalidUrl = 4, + FailedReload = 5, + Discarded = 6, +} diff --git a/azalea-protocol/src/packets/config/s_select_known_packs.rs b/azalea-protocol/src/packets/config/s_select_known_packs.rs new file mode 100644 index 00000000..320b5ca5 --- /dev/null +++ b/azalea-protocol/src/packets/config/s_select_known_packs.rs @@ -0,0 +1,14 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundConfigPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket)] +pub struct ServerboundSelectKnownPacks { + pub known_packs: Vec, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct KnownPack { + pub namespace: String, + pub id: String, + pub version: String, +} diff --git a/azalea-protocol/src/packets/configuration/clientbound_cookie_request_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_cookie_request_packet.rs deleted file mode 100644 index 38566564..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_cookie_request_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundCookieRequestPacket { - pub key: ResourceLocation, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_custom_payload_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_custom_payload_packet.rs deleted file mode 100644 index 701a317c..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_custom_payload_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_buf::UnsizedByteArray; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundCustomPayloadPacket { - pub identifier: ResourceLocation, - pub data: UnsizedByteArray, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_disconnect_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_disconnect_packet.rs deleted file mode 100644 index cd0ed42a..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_disconnect_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundDisconnectPacket { - pub reason: FormattedText, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_finish_configuration_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_finish_configuration_packet.rs deleted file mode 100644 index 81251108..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_finish_configuration_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundFinishConfigurationPacket {} diff --git a/azalea-protocol/src/packets/configuration/clientbound_keep_alive_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_keep_alive_packet.rs deleted file mode 100644 index 83c25610..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_keep_alive_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundKeepAlivePacket { - pub id: u64, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_ping_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_ping_packet.rs deleted file mode 100644 index 968dcaed..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_ping_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundPingPacket { - pub id: u32, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_registry_data_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_registry_data_packet.rs deleted file mode 100644 index 8bada6ca..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_registry_data_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use std::collections::HashMap; - -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; -use simdnbt::owned::NbtCompound; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundRegistryDataPacket { - pub registry_id: ResourceLocation, - pub entries: HashMap>, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_reset_chat_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_reset_chat_packet.rs deleted file mode 100644 index 75afa8c1..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_reset_chat_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundResetChatPacket; diff --git a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_resource_pack_packet.rs deleted file mode 100644 index b05210b5..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundResourcePackPacket { - pub url: String, - pub hash: String, - pub required: bool, - pub prompt: Option, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_pop_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_resource_pack_pop_packet.rs deleted file mode 100644 index 6533b589..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_pop_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundResourcePackPopPacket { - pub id: Option, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_push_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_resource_pack_push_packet.rs deleted file mode 100644 index 798f5f98..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_resource_pack_push_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundConfigurationPacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundResourcePackPushPacket { - pub id: Uuid, - pub url: String, - pub hash: String, - pub required: bool, - pub prompt: Option, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_select_known_packs_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_select_known_packs_packet.rs deleted file mode 100644 index 0f22b054..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_select_known_packs_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -use super::serverbound_select_known_packs_packet::KnownPack; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundSelectKnownPacksPacket { - pub known_packs: Vec, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_store_cookie_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_store_cookie_packet.rs deleted file mode 100644 index fda16689..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_store_cookie_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundStoreCookiePacket { - pub key: ResourceLocation, - pub payload: Vec, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_transfer_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_transfer_packet.rs deleted file mode 100644 index 88f0054a..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_transfer_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundTransferPacket { - pub host: String, - #[var] - pub port: u32, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_update_enabled_features_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_update_enabled_features_packet.rs deleted file mode 100644 index ec37c8f3..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_update_enabled_features_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundUpdateEnabledFeaturesPacket { - pub features: Vec, -} diff --git a/azalea-protocol/src/packets/configuration/clientbound_update_tags_packet.rs b/azalea-protocol/src/packets/configuration/clientbound_update_tags_packet.rs deleted file mode 100644 index 10f66e23..00000000 --- a/azalea-protocol/src/packets/configuration/clientbound_update_tags_packet.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::io::Cursor; -use std::ops::Deref; -use std::{collections::HashMap, io::Write}; - -use azalea_buf::{BufReadError, McBuf, McBufVarReadable, McBufVarWritable}; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] -pub struct ClientboundUpdateTagsPacket { - pub tags: TagMap, -} - -#[derive(Clone, Debug)] -pub struct Tags { - pub name: ResourceLocation, - pub elements: Vec, -} - -#[derive(Clone, Debug)] -pub struct TagMap(pub HashMap>); - -impl McBufReadable for TagMap { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = u32::var_read_from(buf)? as usize; - let mut data = HashMap::with_capacity(length); - for _ in 0..length { - let tag_type = ResourceLocation::read_from(buf)?; - let tags_count = i32::var_read_from(buf)? as usize; - let mut tags_vec = Vec::with_capacity(tags_count); - for _ in 0..tags_count { - let tags = Tags::read_from(buf)?; - tags_vec.push(tags); - } - data.insert(tag_type, tags_vec); - } - Ok(TagMap(data)) - } -} - -impl McBufWritable for TagMap { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (self.len() as u32).var_write_into(buf)?; - for (k, v) in &self.0 { - k.write_into(buf)?; - v.write_into(buf)?; - } - Ok(()) - } -} -impl McBufReadable for Tags { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let name = ResourceLocation::read_from(buf)?; - let elements = Vec::::var_read_from(buf)?; - Ok(Tags { name, elements }) - } -} - -impl McBufWritable for Tags { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.name.write_into(buf)?; - self.elements.var_write_into(buf)?; - Ok(()) - } -} - -impl Deref for TagMap { - type Target = HashMap>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/azalea-protocol/src/packets/configuration/mod.rs b/azalea-protocol/src/packets/configuration/mod.rs deleted file mode 100755 index 757c496c..00000000 --- a/azalea-protocol/src/packets/configuration/mod.rs +++ /dev/null @@ -1,56 +0,0 @@ -pub mod clientbound_cookie_request_packet; -pub mod clientbound_custom_payload_packet; -pub mod clientbound_disconnect_packet; -pub mod clientbound_finish_configuration_packet; -pub mod clientbound_keep_alive_packet; -pub mod clientbound_ping_packet; -pub mod clientbound_registry_data_packet; -pub mod clientbound_reset_chat_packet; -pub mod clientbound_resource_pack_pop_packet; -pub mod clientbound_resource_pack_push_packet; -pub mod clientbound_select_known_packs_packet; -pub mod clientbound_store_cookie_packet; -pub mod clientbound_transfer_packet; -pub mod clientbound_update_enabled_features_packet; -pub mod clientbound_update_tags_packet; -pub mod serverbound_client_information_packet; -pub mod serverbound_cookie_response_packet; -pub mod serverbound_custom_payload_packet; -pub mod serverbound_finish_configuration_packet; -pub mod serverbound_keep_alive_packet; -pub mod serverbound_pong_packet; -pub mod serverbound_resource_pack_packet; -pub mod serverbound_select_known_packs_packet; - -use azalea_protocol_macros::declare_state_packets; - -declare_state_packets!( - ConfigurationPacket, - Serverbound => { - 0x00: serverbound_client_information_packet::ServerboundClientInformationPacket, - 0x01: serverbound_cookie_response_packet::ServerboundCookieResponsePacket, - 0x02: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, - 0x03: serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket, - 0x04: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, - 0x05: serverbound_pong_packet::ServerboundPongPacket, - 0x06: serverbound_resource_pack_packet::ServerboundResourcePackPacket, - 0x07: serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket, - }, - Clientbound => { - 0x00: clientbound_cookie_request_packet::ClientboundCookieRequestPacket, - 0x01: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, - 0x02: clientbound_disconnect_packet::ClientboundDisconnectPacket, - 0x03: clientbound_finish_configuration_packet::ClientboundFinishConfigurationPacket, - 0x04: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, - 0x05: clientbound_ping_packet::ClientboundPingPacket, - 0x06: clientbound_reset_chat_packet::ClientboundResetChatPacket, - 0x07: clientbound_registry_data_packet::ClientboundRegistryDataPacket, - 0x08: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket, - 0x09: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket, - 0x0a: clientbound_store_cookie_packet::ClientboundStoreCookiePacket, - 0x0b: clientbound_transfer_packet::ClientboundTransferPacket, - 0x0c: clientbound_update_enabled_features_packet::ClientboundUpdateEnabledFeaturesPacket, - 0x0d: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, - 0x0e: clientbound_select_known_packs_packet::ClientboundSelectKnownPacksPacket, - } -); diff --git a/azalea-protocol/src/packets/configuration/serverbound_client_information_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_client_information_packet.rs deleted file mode 100644 index b5fd6a35..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_client_information_packet.rs +++ /dev/null @@ -1,193 +0,0 @@ -use azalea_buf::{McBuf, McBufReadable, McBufWritable}; -use azalea_core::bitset::FixedBitSet; -use azalea_protocol_macros::ServerboundConfigurationPacket; -use bevy_ecs::component::Component; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket, PartialEq, Eq)] -pub struct ServerboundClientInformationPacket { - pub information: ClientInformation, -} - -/// A component that contains some of the "settings" for this client that are -/// sent to the server, such as render distance. This is only present on local -/// players. -#[derive(Clone, Debug, McBuf, PartialEq, Eq, Component)] -pub struct ClientInformation { - /// The locale of the client. - pub language: String, - /// The view distance of the client in chunks, same as the render distance - /// in-game. - pub view_distance: u8, - /// The types of chat messages the client wants to receive. Note that many - /// servers ignore this. - pub chat_visibility: ChatVisibility, - /// Whether the messages sent from the server should have colors. Note that - /// many servers ignore this and always send colored messages. - pub chat_colors: bool, - pub model_customization: ModelCustomization, - pub main_hand: HumanoidArm, - pub text_filtering_enabled: bool, - /// Whether the client should show up as "Anonymous Player" in the server - /// list. - pub allows_listing: bool, - pub particle_status: ParticleStatus, -} - -impl Default for ClientInformation { - fn default() -> Self { - Self { - language: "en_us".to_string(), - view_distance: 8, - chat_visibility: ChatVisibility::default(), - chat_colors: true, - model_customization: ModelCustomization::default(), - main_hand: HumanoidArm::Right, - text_filtering_enabled: false, - allows_listing: false, - particle_status: ParticleStatus::default(), - } - } -} - -#[derive(McBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum ChatVisibility { - /// All chat messages should be sent to the client. - #[default] - Full = 0, - /// Chat messages from other players should be not sent to the client, only - /// messages from the server like "Player joined the game" should be sent. - System = 1, - /// No chat messages should be sent to the client. - Hidden = 2, -} - -#[derive(McBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum HumanoidArm { - Left = 0, - #[default] - Right = 1, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct ModelCustomization { - pub cape: bool, - pub jacket: bool, - pub left_sleeve: bool, - pub right_sleeve: bool, - pub left_pants: bool, - pub right_pants: bool, - pub hat: bool, -} - -#[derive(McBuf, Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum ParticleStatus { - #[default] - All, - Decreased, - Minimal, -} - -impl Default for ModelCustomization { - fn default() -> Self { - Self { - cape: true, - jacket: true, - left_sleeve: true, - right_sleeve: true, - left_pants: true, - right_pants: true, - hat: true, - } - } -} - -impl McBufReadable for ModelCustomization { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<7>::read_from(buf)?; - Ok(Self { - cape: set.index(0), - jacket: set.index(1), - left_sleeve: set.index(2), - right_sleeve: set.index(3), - left_pants: set.index(4), - right_pants: set.index(5), - hat: set.index(6), - }) - } -} - -impl McBufWritable for ModelCustomization { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<7>::new(); - if self.cape { - set.set(0); - } - if self.jacket { - set.set(1); - } - if self.left_sleeve { - set.set(2); - } - if self.right_sleeve { - set.set(3); - } - if self.left_pants { - set.set(4); - } - if self.right_pants { - set.set(5); - } - if self.hat { - set.set(6); - } - set.write_into(buf) - } -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use super::*; - - #[test] - fn test_client_information_packet() { - { - let data = ClientInformation::default(); - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - - let read_data = ClientInformation::read_from(&mut data_cursor).unwrap(); - assert_eq!(read_data, data); - } - - { - let data = ClientInformation { - language: "en_gb".to_string(), - view_distance: 24, - chat_visibility: ChatVisibility::Hidden, - chat_colors: false, - model_customization: ModelCustomization { - cape: false, - jacket: false, - left_sleeve: true, - right_sleeve: false, - left_pants: true, - right_pants: false, - hat: true, - }, - main_hand: HumanoidArm::Left, - text_filtering_enabled: true, - allows_listing: true, - particle_status: ParticleStatus::Decreased, - }; - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - - let read_data = ClientInformation::read_from(&mut data_cursor).unwrap(); - assert_eq!(read_data, data); - } - } -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_cookie_response_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_cookie_response_packet.rs deleted file mode 100644 index 6c62c1c8..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_cookie_response_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundCookieResponsePacket { - pub key: ResourceLocation, - pub payload: Option>, -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_custom_payload_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_custom_payload_packet.rs deleted file mode 100644 index 48c977b1..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_custom_payload_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_buf::UnsizedByteArray; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundCustomPayloadPacket { - pub identifier: ResourceLocation, - pub data: UnsizedByteArray, -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_finish_configuration_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_finish_configuration_packet.rs deleted file mode 100644 index 53e04182..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_finish_configuration_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundFinishConfigurationPacket {} diff --git a/azalea-protocol/src/packets/configuration/serverbound_keep_alive_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_keep_alive_packet.rs deleted file mode 100644 index 4604df46..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_keep_alive_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundKeepAlivePacket { - pub id: u64, -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_pong_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_pong_packet.rs deleted file mode 100644 index 153e3fea..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_pong_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundPongPacket { - pub id: u32, -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_resource_pack_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_resource_pack_packet.rs deleted file mode 100644 index 6f35525e..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_resource_pack_packet.rs +++ /dev/null @@ -1,20 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundConfigurationPacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundResourcePackPacket { - pub id: Uuid, - pub action: Action, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - SuccessfullyLoaded = 0, - Declined = 1, - FailedDownload = 2, - Accepted = 3, - InvalidUrl = 4, - FailedReload = 5, - Discarded = 6, -} diff --git a/azalea-protocol/src/packets/configuration/serverbound_select_known_packs_packet.rs b/azalea-protocol/src/packets/configuration/serverbound_select_known_packs_packet.rs deleted file mode 100644 index fe379a17..00000000 --- a/azalea-protocol/src/packets/configuration/serverbound_select_known_packs_packet.rs +++ /dev/null @@ -1,14 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundConfigurationPacket; - -#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)] -pub struct ServerboundSelectKnownPacksPacket { - pub known_packs: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct KnownPack { - pub namespace: String, - pub id: String, - pub version: String, -} diff --git a/azalea-protocol/src/packets/game/c_add_entity.rs b/azalea-protocol/src/packets/game/c_add_entity.rs new file mode 100755 index 00000000..cf0adeb7 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_add_entity.rs @@ -0,0 +1,37 @@ +use azalea_buf::AzBuf; +use azalea_core::{position::Vec3, resource_location::ResourceLocation}; +use azalea_entity::{metadata::apply_default_metadata, EntityBundle}; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundAddEntity { + /// The id of the entity. + #[var] + pub id: u32, + pub uuid: Uuid, + pub entity_type: azalea_registry::EntityKind, + pub position: Vec3, + pub x_rot: i8, + pub y_rot: i8, + pub y_head_rot: i8, + #[var] + pub data: u32, + pub x_vel: i16, + pub y_vel: i16, + pub z_vel: i16, +} + +impl ClientboundAddEntity { + /// Make the entity into a bundle that can be inserted into the ECS. You + /// must apply the metadata after inserting the bundle with + /// [`Self::apply_metadata`]. + pub fn as_entity_bundle(&self, world_name: ResourceLocation) -> EntityBundle { + EntityBundle::new(self.uuid, self.position, self.entity_type, world_name) + } + + /// Apply the default metadata for the given entity. + pub fn apply_metadata(&self, entity: &mut bevy_ecs::system::EntityCommands) { + apply_default_metadata(entity, self.entity_type); + } +} diff --git a/azalea-protocol/src/packets/game/c_add_experience_orb.rs b/azalea-protocol/src/packets/game/c_add_experience_orb.rs new file mode 100755 index 00000000..b3d12858 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_add_experience_orb.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundAddExperienceOrb { + #[var] + pub id: u32, + pub x: f64, + pub y: f64, + pub z: f64, + pub value: u16, +} diff --git a/azalea-protocol/src/packets/game/c_add_player.rs b/azalea-protocol/src/packets/game/c_add_player.rs new file mode 100755 index 00000000..7b36567d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_add_player.rs @@ -0,0 +1,27 @@ +use azalea_buf::AzBuf; +use azalea_core::{ResourceLocation, Vec3}; +use azalea_entity::{metadata::PlayerMetadataBundle, EntityBundle, PlayerBundle}; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::EntityKind; +use uuid::Uuid; + +/// This packet is sent by the server when a player comes into visible range, +/// not when a player joins. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundAddPlayer { + #[var] + pub id: u32, + pub uuid: Uuid, + pub position: Vec3, + pub x_rot: i8, + pub y_rot: i8, +} + +impl ClientboundAddPlayer { + pub fn as_player_bundle(&self, world_name: ResourceLocation) -> PlayerBundle { + PlayerBundle { + entity: EntityBundle::new(self.uuid, self.position, EntityKind::Player, world_name), + metadata: PlayerMetadataBundle::default(), + } + } +} diff --git a/azalea-protocol/src/packets/game/c_animate.rs b/azalea-protocol/src/packets/game/c_animate.rs new file mode 100755 index 00000000..bda0b152 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_animate.rs @@ -0,0 +1,21 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundAnimate { + #[var] + pub id: u32, + pub action: AnimationAction, +} + +// minecraft actually uses a u8 for this, but a varint still works and makes it +// so i don't have to add a special handler +#[derive(Clone, Debug, Copy, AzBuf)] +pub enum AnimationAction { + SwingMainHand = 0, + Hurt = 1, + WakeUp = 2, + SwingOffHand = 3, + CriticalHit = 4, + MagicCriticalHit = 5, +} diff --git a/azalea-protocol/src/packets/game/c_award_stats.rs b/azalea-protocol/src/packets/game/c_award_stats.rs new file mode 100755 index 00000000..20f8b1e0 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_award_stats.rs @@ -0,0 +1,23 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundAwardStats { + #[var] + pub stats: HashMap, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, AzBuf)] +pub enum Stat { + Mined(azalea_registry::Block), + Crafted(azalea_registry::Item), + Used(azalea_registry::Item), + Broken(azalea_registry::Item), + PickedUp(azalea_registry::Item), + Dropped(azalea_registry::Item), + Killed(azalea_registry::EntityKind), + KilledBy(azalea_registry::EntityKind), + Custom(azalea_registry::CustomStat), +} diff --git a/azalea-protocol/src/packets/game/c_block_changed_ack.rs b/azalea-protocol/src/packets/game/c_block_changed_ack.rs new file mode 100755 index 00000000..ebb303c0 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_block_changed_ack.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBlockChangedAck { + #[var] + pub sequence: i32, +} diff --git a/azalea-protocol/src/packets/game/c_block_destruction.rs b/azalea-protocol/src/packets/game/c_block_destruction.rs new file mode 100755 index 00000000..50d8085b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_block_destruction.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBlockDestruction { + /// The ID of the entity breaking the block. + #[var] + pub id: u32, + pub pos: BlockPos, + /// 0–9 to set it, any other value to remove it. + pub progress: u8, +} diff --git a/azalea-protocol/src/packets/game/c_block_entity_data.rs b/azalea-protocol/src/packets/game/c_block_entity_data.rs new file mode 100755 index 00000000..82ba60de --- /dev/null +++ b/azalea-protocol/src/packets/game/c_block_entity_data.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; +use simdnbt::owned::Nbt; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBlockEntityData { + pub pos: BlockPos, + pub block_entity_type: azalea_registry::BlockEntityKind, + pub tag: Nbt, +} diff --git a/azalea-protocol/src/packets/game/c_block_event.rs b/azalea-protocol/src/packets/game/c_block_event.rs new file mode 100755 index 00000000..3a71b186 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_block_event.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::Block; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBlockEvent { + pub pos: BlockPos, + pub action_id: u8, + pub action_parameter: u8, + pub block: Block, +} diff --git a/azalea-protocol/src/packets/game/c_block_update.rs b/azalea-protocol/src/packets/game/c_block_update.rs new file mode 100755 index 00000000..ae9bd998 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_block_update.rs @@ -0,0 +1,10 @@ +use azalea_block::BlockState; +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBlockUpdate { + pub pos: BlockPos, + pub block_state: BlockState, +} diff --git a/azalea-protocol/src/packets/game/c_boss_event.rs b/azalea-protocol/src/packets/game/c_boss_event.rs new file mode 100755 index 00000000..e54ab59f --- /dev/null +++ b/azalea-protocol/src/packets/game/c_boss_event.rs @@ -0,0 +1,143 @@ +use std::io::Cursor; +use std::io::Write; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_chat::FormattedText; +use azalea_core::bitset::FixedBitSet; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBossEvent { + pub id: Uuid, + pub operation: Operation, +} + +#[derive(Clone, Debug)] +pub enum Operation { + Add(AddOperation), + Remove, + UpdateProgress(f32), + UpdateName(FormattedText), + UpdateStyle(Style), + UpdateProperties(Properties), +} + +impl AzaleaRead for Operation { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let operation_id = u32::azalea_read_var(buf)?; + Ok(match operation_id { + 0 => Operation::Add(AddOperation::azalea_read(buf)?), + 1 => Operation::Remove, + 2 => Operation::UpdateProgress(f32::azalea_read(buf)?), + 3 => Operation::UpdateName(FormattedText::azalea_read(buf)?), + 4 => Operation::UpdateStyle(Style::azalea_read(buf)?), + 5 => Operation::UpdateProperties(Properties::azalea_read(buf)?), + _ => { + return Err(BufReadError::UnexpectedEnumVariant { + id: operation_id as i32, + }) + } + }) + } +} + +impl AzaleaWrite for Operation { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Operation::Add(add) => { + 0u32.azalea_write_var(buf)?; + add.azalea_write(buf)?; + } + Operation::Remove => { + 1u32.azalea_write_var(buf)?; + } + Operation::UpdateProgress(progress) => { + 2u32.azalea_write_var(buf)?; + progress.azalea_write(buf)?; + } + Operation::UpdateName(name) => { + 3u32.azalea_write_var(buf)?; + name.azalea_write(buf)?; + } + Operation::UpdateStyle(style) => { + 4u32.azalea_write_var(buf)?; + style.azalea_write(buf)?; + } + Operation::UpdateProperties(properties) => { + 5u32.azalea_write_var(buf)?; + properties.azalea_write(buf)?; + } + } + Ok(()) + } +} + +#[derive(Clone, Debug, AzBuf)] +pub struct AddOperation { + pub name: FormattedText, + pub progress: f32, + pub style: Style, + pub properties: Properties, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct Style { + pub color: BossBarColor, + pub overlay: BossBarOverlay, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum BossBarColor { + Pink = 0, + Blue = 1, + Red = 2, + Green = 3, + Yellow = 4, + Purple = 5, + White = 6, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum BossBarOverlay { + Progress = 0, + Notched6 = 1, + Notched10 = 2, + Notched12 = 3, + Notched20 = 4, +} + +#[derive(Clone, Debug)] +pub struct Properties { + pub darken_screen: bool, + pub play_music: bool, + pub create_world_fog: bool, +} + +impl AzaleaRead for Properties { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<3>::azalea_read(buf)?; + Ok(Self { + darken_screen: set.index(0), + play_music: set.index(1), + create_world_fog: set.index(2), + }) + } +} + +impl AzaleaWrite for Properties { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<3>::new(); + if self.darken_screen { + set.set(0); + } + if self.play_music { + set.set(1); + } + if self.create_world_fog { + set.set(2); + } + set.azalea_write(buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/c_bundle_delimiter.rs b/azalea-protocol/src/packets/game/c_bundle_delimiter.rs new file mode 100644 index 00000000..cda33d1b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_bundle_delimiter.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundBundleDelimiter; diff --git a/azalea-protocol/src/packets/game/c_change_difficulty.rs b/azalea-protocol/src/packets/game/c_change_difficulty.rs new file mode 100755 index 00000000..cdcc4792 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_change_difficulty.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::difficulty::Difficulty; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundChangeDifficulty { + pub difficulty: Difficulty, + pub locked: bool, +} diff --git a/azalea-protocol/src/packets/game/c_chat_preview.rs b/azalea-protocol/src/packets/game/c_chat_preview.rs new file mode 100755 index 00000000..e0ddd2ec --- /dev/null +++ b/azalea-protocol/src/packets/game/c_chat_preview.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundChatPreview { + pub query_id: i32, + pub preview: Option, +} diff --git a/azalea-protocol/src/packets/game/c_chunk_batch_finished.rs b/azalea-protocol/src/packets/game/c_chunk_batch_finished.rs new file mode 100644 index 00000000..c419888b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_chunk_batch_finished.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundChunkBatchFinished { + #[var] + pub batch_size: u32, +} diff --git a/azalea-protocol/src/packets/game/c_chunk_batch_start.rs b/azalea-protocol/src/packets/game/c_chunk_batch_start.rs new file mode 100644 index 00000000..8b0555dc --- /dev/null +++ b/azalea-protocol/src/packets/game/c_chunk_batch_start.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundChunkBatchStart {} diff --git a/azalea-protocol/src/packets/game/c_chunks_biomes.rs b/azalea-protocol/src/packets/game/c_chunks_biomes.rs new file mode 100644 index 00000000..a8e65af4 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_chunks_biomes.rs @@ -0,0 +1,14 @@ +use azalea_buf::AzBuf; +use azalea_core::position::ChunkPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundChunksBiomes { + pub chunk_biome_data: Vec, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct ChunkBiomeData { + pub pos: ChunkPos, + pub buffer: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_clear_titles.rs b/azalea-protocol/src/packets/game/c_clear_titles.rs new file mode 100644 index 00000000..58b67bad --- /dev/null +++ b/azalea-protocol/src/packets/game/c_clear_titles.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundClearTitles { + pub reset_times: bool, +} diff --git a/azalea-protocol/src/packets/game/c_command_suggestions.rs b/azalea-protocol/src/packets/game/c_command_suggestions.rs new file mode 100755 index 00000000..37679a72 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_command_suggestions.rs @@ -0,0 +1,37 @@ +use azalea_brigadier::suggestion::Suggestions; +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCommandSuggestions { + #[var] + pub id: u32, + pub suggestions: Suggestions, +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_brigadier::{context::StringRange, suggestion::Suggestion}; + use azalea_buf::{AzaleaRead, AzaleaWrite}; + + use super::*; + + #[test] + fn test_suggestions() { + let suggestions = Suggestions::new( + StringRange::new(0, 5), + vec![Suggestion::new_with_tooltip( + StringRange::new(1, 4), + "foo", + "bar".to_string(), + )], + ); + let mut buf = Vec::new(); + suggestions.azalea_write(&mut buf).unwrap(); + let mut cursor = Cursor::new(&buf[..]); + let suggestions = Suggestions::azalea_read(&mut cursor).unwrap(); + assert_eq!(suggestions, suggestions); + } +} diff --git a/azalea-protocol/src/packets/game/c_commands.rs b/azalea-protocol/src/packets/game/c_commands.rs new file mode 100755 index 00000000..1a231559 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_commands.rs @@ -0,0 +1,378 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_core::{bitset::FixedBitSet, resource_location::ResourceLocation}; +use azalea_protocol_macros::ClientboundGamePacket; +use tracing::warn; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCommands { + pub entries: Vec, + #[var] + pub root_index: u32, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct BrigadierNodeStub { + pub is_executable: bool, + pub children: Vec, + pub redirect_node: Option, + pub node_type: NodeType, +} + +#[derive(Debug, Clone, Eq)] +pub struct BrigadierNumber { + pub min: Option, + pub max: Option, +} +impl BrigadierNumber { + pub fn new(min: Option, max: Option) -> BrigadierNumber { + BrigadierNumber { min, max } + } +} +impl PartialEq for BrigadierNumber { + fn eq(&self, other: &Self) -> bool { + match (&self.min, &self.max, &other.min, &other.max) { + (Some(f_min), None, Some(s_min), None) => f_min == s_min, + (None, Some(f_max), None, Some(s_max)) => f_max == s_max, + (Some(f_min), Some(f_max), Some(s_min), Some(s_max)) => { + f_min == s_min && f_max == s_max + } + (None, None, None, None) => true, + _ => false, + } + } +} + +impl AzaleaRead for BrigadierNumber { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let flags = FixedBitSet::<2>::azalea_read(buf)?; + let min = if flags.index(0) { + Some(T::azalea_read(buf)?) + } else { + None + }; + let max = if flags.index(1) { + Some(T::azalea_read(buf)?) + } else { + None + }; + Ok(BrigadierNumber { min, max }) + } +} +impl AzaleaWrite for BrigadierNumber { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut flags = FixedBitSet::<2>::new(); + if self.min.is_some() { + flags.set(0); + } + if self.max.is_some() { + flags.set(1); + } + flags.azalea_write(buf)?; + if let Some(min) = &self.min { + min.azalea_write(buf)?; + } + if let Some(max) = &self.max { + max.azalea_write(buf)?; + } + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, AzBuf, PartialEq, Eq)] +pub enum BrigadierString { + /// Reads a single word + SingleWord = 0, + // If it starts with a ", keeps reading until another " (allowing escaping with \). Otherwise + // behaves the same as SINGLE_WORD + QuotablePhrase = 1, + // Reads the rest of the content after the cursor. Quotes will not be removed. + GreedyPhrase = 2, +} + +#[derive(Debug, Clone, AzBuf, PartialEq)] +pub enum BrigadierParser { + Bool, + Float(BrigadierNumber), + Double(BrigadierNumber), + Integer(BrigadierNumber), + Long(BrigadierNumber), + String(BrigadierString), + Entity(EntityParser), + GameProfile, + BlockPos, + ColumnPos, + Vec3, + Vec2, + BlockState, + BlockPredicate, + ItemStack, + ItemPredicate, + Color, + FormattedText, + Style, + Message, + NbtCompoundTag, + NbtTag, + NbtPath, + Objective, + ObjectiveCriteria, + Operation, + Particle, + Angle, + Rotation, + ScoreboardSlot, + ScoreHolder { allows_multiple: bool }, + Swizzle, + Team, + ItemSlot, + ItemSlots, + ResourceLocation, + Function, + EntityAnchor, + IntRange, + FloatRange, + Dimension, + GameMode, + Time { min: i32 }, + ResourceOrTag { registry_key: ResourceLocation }, + ResourceOrTagKey { registry_key: ResourceLocation }, + Resource { registry_key: ResourceLocation }, + ResourceKey { registry_key: ResourceLocation }, + TemplateMirror, + TemplateRotation, + Heightmap, + LootTable, + LootPredicate, + LootModifier, + Uuid, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EntityParser { + pub single: bool, + pub players_only: bool, +} +impl AzaleaRead for EntityParser { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let flags = FixedBitSet::<2>::azalea_read(buf)?; + Ok(EntityParser { + single: flags.index(0), + players_only: flags.index(1), + }) + } +} +impl AzaleaWrite for EntityParser { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut flags = FixedBitSet::<2>::new(); + if self.single { + flags.set(0); + } + if self.players_only { + flags.set(1); + } + flags.azalea_write(buf)?; + Ok(()) + } +} + +// TODO: BrigadierNodeStub should have more stuff +impl AzaleaRead for BrigadierNodeStub { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let flags = FixedBitSet::<8>::azalea_read(buf)?; + if flags.index(5) || flags.index(6) || flags.index(7) { + warn!("Warning: The flags from a Brigadier node are over 31. This is probably a bug.",); + } + + let node_type = u8::from(flags.index(0)) + (u8::from(flags.index(1)) * 2); + let is_executable = flags.index(2); + let has_redirect = flags.index(3); + let has_suggestions_type = flags.index(4); + + let children = Vec::::azalea_read_var(buf)?; + let redirect_node = if has_redirect { + Some(u32::azalea_read_var(buf)?) + } else { + None + }; + + // argument node + if node_type == 2 { + let name = String::azalea_read(buf)?; + let parser = BrigadierParser::azalea_read(buf)?; + let suggestions_type = if has_suggestions_type { + Some(ResourceLocation::azalea_read(buf)?) + } else { + None + }; + let node = BrigadierNodeStub { + is_executable, + children, + redirect_node, + node_type: NodeType::Argument { + name, + parser, + suggestions_type, + }, + }; + return Ok(node); + } + // literal node + else if node_type == 1 { + let name = String::azalea_read(buf)?; + return Ok(BrigadierNodeStub { + is_executable, + children, + redirect_node, + node_type: NodeType::Literal { name }, + }); + } + Ok(BrigadierNodeStub { + is_executable, + children, + redirect_node, + node_type: NodeType::Root, + }) + } +} + +impl AzaleaWrite for BrigadierNodeStub { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut flags = FixedBitSet::<4>::new(); + if self.is_executable { + flags.set(2); + } + if self.redirect_node.is_some() { + flags.set(3); + } + + match &self.node_type { + NodeType::Root => { + flags.azalea_write(buf)?; + + self.children.azalea_write_var(buf)?; + + if let Some(redirect) = self.redirect_node { + redirect.azalea_write_var(buf)?; + } + } + NodeType::Literal { name } => { + flags.set(0); + flags.azalea_write(buf)?; + + self.children.azalea_write_var(buf)?; + + if let Some(redirect) = self.redirect_node { + redirect.azalea_write_var(buf)?; + } + + name.azalea_write(buf)?; + } + NodeType::Argument { + name, + parser, + suggestions_type, + } => { + flags.set(1); + if suggestions_type.is_some() { + flags.set(4); + } + flags.azalea_write(buf)?; + + self.children.azalea_write_var(buf)?; + + if let Some(redirect) = self.redirect_node { + redirect.azalea_write_var(buf)?; + } + + name.azalea_write(buf)?; + parser.azalea_write(buf)?; + + if let Some(suggestion) = suggestions_type { + suggestion.azalea_write(buf)?; + } + } + } + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum NodeType { + Root, + Literal { + name: String, + }, + Argument { + name: String, + parser: BrigadierParser, + suggestions_type: Option, + }, +} + +impl BrigadierNodeStub { + #[must_use] + pub fn name(&self) -> Option<&str> { + match &self.node_type { + NodeType::Root => None, + NodeType::Literal { name } | NodeType::Argument { name, .. } => Some(name), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_brigadier_node_stub_root() { + let data = BrigadierNodeStub { + is_executable: false, + children: vec![1, 2], + redirect_node: None, + node_type: NodeType::Root, + }; + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + let read_data = BrigadierNodeStub::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(data, read_data); + } + + #[test] + fn test_brigadier_node_stub_literal() { + let data = BrigadierNodeStub { + is_executable: true, + children: vec![], + redirect_node: None, + node_type: NodeType::Literal { + name: "String".to_string(), + }, + }; + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + let read_data = BrigadierNodeStub::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(data, read_data); + } + + #[test] + fn test_brigadier_node_stub_argument() { + let data = BrigadierNodeStub { + is_executable: false, + children: vec![6, 9], + redirect_node: Some(5), + node_type: NodeType::Argument { + name: "position".to_string(), + parser: BrigadierParser::Vec3, + suggestions_type: Some(ResourceLocation::new("minecraft:test_suggestion")), + }, + }; + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + let read_data = BrigadierNodeStub::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(data, read_data); + } +} diff --git a/azalea-protocol/src/packets/game/c_container_close.rs b/azalea-protocol/src/packets/game/c_container_close.rs new file mode 100644 index 00000000..dda6153b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_container_close.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundContainerClose { + pub container_id: u8, +} diff --git a/azalea-protocol/src/packets/game/c_container_set_content.rs b/azalea-protocol/src/packets/game/c_container_set_content.rs new file mode 100755 index 00000000..852ce60f --- /dev/null +++ b/azalea-protocol/src/packets/game/c_container_set_content.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundContainerSetContent { + pub container_id: i8, + #[var] + pub state_id: u32, + pub items: Vec, + pub carried_item: ItemStack, +} diff --git a/azalea-protocol/src/packets/game/c_container_set_data.rs b/azalea-protocol/src/packets/game/c_container_set_data.rs new file mode 100755 index 00000000..3815f5c5 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_container_set_data.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundContainerSetData { + pub container_id: i8, + pub id: u16, + pub value: u16, +} diff --git a/azalea-protocol/src/packets/game/c_container_set_slot.rs b/azalea-protocol/src/packets/game/c_container_set_slot.rs new file mode 100755 index 00000000..5e3476d9 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_container_set_slot.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundContainerSetSlot { + pub container_id: i8, + #[var] + pub state_id: u32, + pub slot: u16, + pub item_stack: ItemStack, +} diff --git a/azalea-protocol/src/packets/game/c_cookie_request.rs b/azalea-protocol/src/packets/game/c_cookie_request.rs new file mode 100755 index 00000000..330b7334 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_cookie_request.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCookieRequest { + pub key: ResourceLocation, +} diff --git a/azalea-protocol/src/packets/game/c_cooldown.rs b/azalea-protocol/src/packets/game/c_cooldown.rs new file mode 100755 index 00000000..016101b7 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_cooldown.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCooldown { + pub item: azalea_registry::Item, + #[var] + pub duration: u32, +} diff --git a/azalea-protocol/src/packets/game/c_custom_chat_completions.rs b/azalea-protocol/src/packets/game/c_custom_chat_completions.rs new file mode 100755 index 00000000..87c27b7a --- /dev/null +++ b/azalea-protocol/src/packets/game/c_custom_chat_completions.rs @@ -0,0 +1,15 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCustomChatCompletions { + pub action: Action, + pub entries: Vec, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + Add = 0, + Remove = 1, + Set = 2, +} diff --git a/azalea-protocol/src/packets/game/c_custom_payload.rs b/azalea-protocol/src/packets/game/c_custom_payload.rs new file mode 100755 index 00000000..0610d63e --- /dev/null +++ b/azalea-protocol/src/packets/game/c_custom_payload.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_buf::UnsizedByteArray; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCustomPayload { + pub identifier: ResourceLocation, + pub data: UnsizedByteArray, +} diff --git a/azalea-protocol/src/packets/game/c_custom_report_details.rs b/azalea-protocol/src/packets/game/c_custom_report_details.rs new file mode 100644 index 00000000..85eccfb7 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_custom_report_details.rs @@ -0,0 +1,14 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCustomReportDetails { + // azalea doesn't implement max lengths yet + + // max length = 32 + // key string is limited to 128 bytes + // value string is limited to 4096 bytes + pub details: HashMap, +} diff --git a/azalea-protocol/src/packets/game/c_custom_sound.rs b/azalea-protocol/src/packets/game/c_custom_sound.rs new file mode 100644 index 00000000..7daadb3a --- /dev/null +++ b/azalea-protocol/src/packets/game/c_custom_sound.rs @@ -0,0 +1,28 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundCustomSound { + pub name: ResourceLocation, + pub source: SoundSource, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum SoundSource { + Master = 0, + Music = 1, + Records = 2, + Weather = 3, + Blocks = 4, + Hostile = 5, + Neutral = 6, + Players = 7, + Ambient = 8, + Voice = 9, +} diff --git a/azalea-protocol/src/packets/game/c_damage_event.rs b/azalea-protocol/src/packets/game/c_damage_event.rs new file mode 100644 index 00000000..a736f39a --- /dev/null +++ b/azalea-protocol/src/packets/game/c_damage_event.rs @@ -0,0 +1,35 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWriteVar, AzaleaWrite}; +use azalea_core::position::Vec3; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundDamageEvent { + #[var] + pub entity_id: u32, + #[var] + pub source_type_id: u32, + pub source_cause_id: OptionalEntityId, + pub source_direct_id: OptionalEntityId, + pub source_position: Option, +} + +#[derive(Clone, Debug)] +pub struct OptionalEntityId(pub Option); +impl AzaleaRead for OptionalEntityId { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + match u32::azalea_read_var(buf)? { + 0 => Ok(OptionalEntityId(None)), + id => Ok(OptionalEntityId(Some(id - 1))), + } + } +} +impl AzaleaWrite for OptionalEntityId { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self.0 { + Some(id) => (id + 1).azalea_write_var(buf), + None => 0u32.azalea_write_var(buf), + } + } +} diff --git a/azalea-protocol/src/packets/game/c_debug_sample.rs b/azalea-protocol/src/packets/game/c_debug_sample.rs new file mode 100755 index 00000000..50550062 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_debug_sample.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::s_debug_sample_subscription::RemoteDebugSampleType; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundDebugSample { + pub sample: Vec, + pub debug_sample_type: RemoteDebugSampleType, +} diff --git a/azalea-protocol/src/packets/game/c_delete_chat.rs b/azalea-protocol/src/packets/game/c_delete_chat.rs new file mode 100755 index 00000000..d44a4553 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_delete_chat.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::c_player_chat::PackedMessageSignature; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundDeleteChat { + pub signature: PackedMessageSignature, +} diff --git a/azalea-protocol/src/packets/game/c_disconnect.rs b/azalea-protocol/src/packets/game/c_disconnect.rs new file mode 100755 index 00000000..ba197f1d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_disconnect.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundDisconnect { + pub reason: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_disguised_chat.rs b/azalea-protocol/src/packets/game/c_disguised_chat.rs new file mode 100644 index 00000000..90dc5d64 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_disguised_chat.rs @@ -0,0 +1,42 @@ +use azalea_buf::AzBuf; +use azalea_chat::{ + translatable_component::{StringOrComponent, TranslatableComponent}, + FormattedText, +}; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::c_player_chat::ChatTypeBound; + +// A disguised chat packet is basically the same as a normal +// [`ClientboundPlayerChat`], except that it doesn't have any of the chat +// signing things. Vanilla servers use this when messages are sent from the +// console. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket, PartialEq)] +pub struct ClientboundDisguisedChat { + pub message: FormattedText, + pub chat_type: ChatTypeBound, +} + +impl ClientboundDisguisedChat { + /// Get the full message, including the sender part. + #[must_use] + pub fn message(&self) -> FormattedText { + let sender = self.chat_type.name.clone(); + let content = self.message.clone(); + let target = self.chat_type.target_name.clone(); + + let translation_key = self.chat_type.chat_type.chat_translation_key(); + + let mut args = vec![ + StringOrComponent::FormattedText(sender), + StringOrComponent::FormattedText(content), + ]; + if let Some(target) = target { + args.push(StringOrComponent::FormattedText(target)); + } + + let component = TranslatableComponent::new(translation_key.to_string(), args); + + FormattedText::Translatable(component) + } +} diff --git a/azalea-protocol/src/packets/game/c_entity_event.rs b/azalea-protocol/src/packets/game/c_entity_event.rs new file mode 100755 index 00000000..13efbabd --- /dev/null +++ b/azalea-protocol/src/packets/game/c_entity_event.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundEntityEvent { + pub entity_id: u32, + pub event_id: u8, +} diff --git a/azalea-protocol/src/packets/game/c_entity_position_sync.rs b/azalea-protocol/src/packets/game/c_entity_position_sync.rs new file mode 100755 index 00000000..c5cde322 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_entity_position_sync.rs @@ -0,0 +1,19 @@ +use azalea_buf::AzBuf; +use azalea_core::position::Vec3; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundEntityPositionSync { + #[var] + pub id: u32, + pub values: PositionMoveRotation, + pub on_ground: bool, +} + +#[derive(AzBuf, Clone, Debug)] +pub struct PositionMoveRotation { + pub position: Vec3, + pub delta_movement: Vec3, + pub y_rot: f32, + pub x_rot: f32, +} diff --git a/azalea-protocol/src/packets/game/c_explode.rs b/azalea-protocol/src/packets/game/c_explode.rs new file mode 100755 index 00000000..aef3887d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_explode.rs @@ -0,0 +1,164 @@ +use std::{ + io::{Cursor, Write}, + str::FromStr, +}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_core::{position::BlockPos, resource_location::ResourceLocation}; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::{ParticleKind, SoundEvent}; + +#[derive(Clone, Debug, PartialEq, ClientboundGamePacket)] +pub struct ClientboundExplode { + pub x: f64, + pub y: f64, + pub z: f64, + pub power: f32, + pub to_blow: Vec, + pub knockback_x: f32, + pub knockback_y: f32, + pub knockback_z: f32, + pub block_interaction: BlockInteraction, + pub small_explosion_particles: ParticleKind, + pub large_explosion_particles: ParticleKind, + pub explosion_sound: SoundEvent, +} + +#[derive(Clone, Copy, Debug, PartialEq, AzBuf)] +pub enum BlockInteraction { + Keep, + Destroy, + DestroyWithDecay, + TriggerBlock, +} + +impl AzaleaRead for ClientboundExplode { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let x = f64::azalea_read(buf)?; + let y = f64::azalea_read(buf)?; + let z = f64::azalea_read(buf)?; + let power = f32::azalea_read(buf)?; + + let x_floor = x.floor() as i32; + let y_floor = y.floor() as i32; + let z_floor = z.floor() as i32; + + let to_blow_len = u32::azalea_read_var(buf)?; + let mut to_blow = Vec::with_capacity(to_blow_len as usize); + for _ in 0..to_blow_len { + // the bytes are offsets from the main x y z + let x = x_floor + i32::from(i8::azalea_read(buf)?); + let y = y_floor + i32::from(i8::azalea_read(buf)?); + let z = z_floor + i32::from(i8::azalea_read(buf)?); + to_blow.push(BlockPos { x, y, z }); + } + + let knockback_x = f32::azalea_read(buf)?; + let knockback_y = f32::azalea_read(buf)?; + let knockback_z = f32::azalea_read(buf)?; + + let block_interaction = BlockInteraction::azalea_read(buf)?; + let small_explosion_particles = ParticleKind::azalea_read(buf)?; + let large_explosion_particles = ParticleKind::azalea_read(buf)?; + + let sound_event_resource_location = ResourceLocation::azalea_read(buf)?.to_string(); + let explosion_sound = + SoundEvent::from_str(&sound_event_resource_location).map_err(|_| { + BufReadError::UnexpectedStringEnumVariant { + id: sound_event_resource_location, + } + })?; + + Ok(Self { + x, + y, + z, + power, + to_blow, + knockback_x, + knockback_y, + knockback_z, + block_interaction, + small_explosion_particles, + large_explosion_particles, + explosion_sound, + }) + } +} + +impl AzaleaWrite for ClientboundExplode { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.x.azalea_write(buf)?; + self.y.azalea_write(buf)?; + self.z.azalea_write(buf)?; + self.power.azalea_write(buf)?; + + let to_blow_len = self.to_blow.len() as u32; + to_blow_len.azalea_write_var(buf)?; + + let x_floor = self.x.floor() as i32; + let y_floor = self.y.floor() as i32; + let z_floor = self.z.floor() as i32; + + for pos in &self.to_blow { + let x = (pos.x - x_floor) as i8; + let y = (pos.y - y_floor) as i8; + let z = (pos.z - z_floor) as i8; + x.azalea_write(buf)?; + y.azalea_write(buf)?; + z.azalea_write(buf)?; + } + + self.knockback_x.azalea_write(buf)?; + self.knockback_y.azalea_write(buf)?; + self.knockback_z.azalea_write(buf)?; + + self.block_interaction.azalea_write(buf)?; + self.small_explosion_particles.azalea_write(buf)?; + self.large_explosion_particles.azalea_write(buf)?; + + let sound_event_resource_location = + ResourceLocation::new(&self.explosion_sound.to_string()); + sound_event_resource_location.azalea_write(buf)?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_read_write() { + let packet = ClientboundExplode { + x: 123_456.0, + y: 789_012.0, + z: 345_678.0, + power: 1_000.0, + to_blow: vec![ + BlockPos { + x: 123_456 + 1, + y: 789_012 + 2, + z: 345_678 - 127, + }, + BlockPos { + x: 123_456 + 4, + y: 789_012 - 5, + z: 345_678 + 6, + }, + ], + knockback_x: 1_000.0, + knockback_y: 2_000.0, + knockback_z: 3_000.0, + block_interaction: BlockInteraction::Destroy, + small_explosion_particles: ParticleKind::Explosion, + large_explosion_particles: ParticleKind::ExplosionEmitter, + explosion_sound: SoundEvent::EntityGenericExplode, + }; + let mut buf = Vec::new(); + packet.azalea_write(&mut buf).unwrap(); + let packet2 = ClientboundExplode::azalea_read(&mut Cursor::new(&buf)).unwrap(); + assert_eq!(packet, packet2); + } +} diff --git a/azalea-protocol/src/packets/game/c_forget_level_chunk.rs b/azalea-protocol/src/packets/game/c_forget_level_chunk.rs new file mode 100755 index 00000000..bd901634 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_forget_level_chunk.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::position::ChunkPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundForgetLevelChunk { + pub pos: ChunkPos, +} diff --git a/azalea-protocol/src/packets/game/c_game_event.rs b/azalea-protocol/src/packets/game/c_game_event.rs new file mode 100755 index 00000000..940aa2f1 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_game_event.rs @@ -0,0 +1,26 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundGameEvent { + pub event: EventType, + pub param: f32, +} + +#[derive(Clone, Debug, Copy, AzBuf)] +pub enum EventType { + NoRespawnBlockAvailable = 0, + StartRaining = 1, + StopRaining = 2, + ChangeGameMode = 3, + WinGame = 4, + DemoEvent = 5, + ArrowHitPlayer = 6, + RainLevelChange = 7, + ThunderLevelChange = 8, + PufferFishSting = 9, + GuardianElderEffect = 10, + ImmediateRespawn = 11, + LimitedCrafting = 12, + WaitForLevelChunks = 13, +} diff --git a/azalea-protocol/src/packets/game/c_horse_screen_open.rs b/azalea-protocol/src/packets/game/c_horse_screen_open.rs new file mode 100755 index 00000000..13a67253 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_horse_screen_open.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundHorseScreenOpen { + pub container_id: u8, + #[var] + pub size: u32, + pub entity_id: u32, +} diff --git a/azalea-protocol/src/packets/game/c_hurt_animation.rs b/azalea-protocol/src/packets/game/c_hurt_animation.rs new file mode 100644 index 00000000..49a32989 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_hurt_animation.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundHurtAnimation { + #[var] + pub id: u32, + pub yaw: f32, +} diff --git a/azalea-protocol/src/packets/game/c_initialize_border.rs b/azalea-protocol/src/packets/game/c_initialize_border.rs new file mode 100755 index 00000000..ca338b7f --- /dev/null +++ b/azalea-protocol/src/packets/game/c_initialize_border.rs @@ -0,0 +1,18 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, ClientboundGamePacket, AzBuf)] +pub struct ClientboundInitializeBorder { + pub new_center_x: f64, + pub new_center_z: f64, + pub old_size: f64, + pub new_size: f64, + #[var] + pub lerp_time: u64, + #[var] + pub new_absolute_max_size: u32, + #[var] + pub warning_blocks: u32, + #[var] + pub warning_time: u32, +} diff --git a/azalea-protocol/src/packets/game/c_keep_alive.rs b/azalea-protocol/src/packets/game/c_keep_alive.rs new file mode 100755 index 00000000..ff93560b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_keep_alive.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundKeepAlive { + pub id: u64, +} diff --git a/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs b/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs new file mode 100755 index 00000000..a4a6da45 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs @@ -0,0 +1,65 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use simdnbt::owned::Nbt; + +use super::c_light_update::ClientboundLightUpdatePacketData; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundLevelChunkWithLight { + pub x: i32, + pub z: i32, + pub chunk_data: ClientboundLevelChunkPacketData, + pub light_data: ClientboundLightUpdatePacketData, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct ClientboundLevelChunkPacketData { + pub heightmaps: Nbt, + // we can't parse the data in azalea-protocol because it depends on context from other packets + pub data: Vec, + pub block_entities: Vec, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct BlockEntity { + pub packed_xz: u8, + pub y: u16, + pub kind: azalea_registry::BlockEntityKind, + pub data: Nbt, +} + +#[cfg(test)] +mod tests { + use std::{io::Cursor, ops::Deref}; + + use azalea_buf::AzaleaRead; + use azalea_world::Chunk; + use simdnbt::owned::BaseNbt; + + use super::*; + + #[test] + fn test_c_level_chunk_with_light_packet() { + #[rustfmt::skip] + let bytes = [ + 255, 255, 255, 253, 0, 0, 0, 1, 10, 12, 0, 15, 77, 79, 84, 73, 79, 78, 95, 66, 76, 79, 67, 75, 73, 78, 71, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 240, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 33, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 37, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 2, 0, 137, 51, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 2, 0, 137, 51, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 4, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 32, 67, 101, 0, 0, 0, 0, 0, 32, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 33, 67, 101, 135, 169, 203, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 33, 67, 101, 135, 169, 203, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]; + + let packet = ClientboundLevelChunkWithLight::azalea_read(&mut Cursor::new(&bytes)).unwrap(); + + let heightmaps_nbt = &packet.chunk_data.heightmaps; + // necessary to make the unwrap_or work + let empty_nbt = BaseNbt::default(); + let heightmaps = heightmaps_nbt.unwrap_or(&empty_nbt).deref(); + + let chunk = Chunk::read_with_dimension_height( + &mut Cursor::new(&packet.chunk_data.data), + 256, + 0, + heightmaps, + ) + .unwrap(); + + assert_eq!(chunk.sections.len(), 16); + } +} diff --git a/azalea-protocol/src/packets/game/c_level_event.rs b/azalea-protocol/src/packets/game/c_level_event.rs new file mode 100755 index 00000000..f41a1f42 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_level_event.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundLevelEvent { + pub event_type: u32, + pub pos: BlockPos, + pub data: u32, + pub global_event: bool, +} diff --git a/azalea-protocol/src/packets/game/c_level_particles.rs b/azalea-protocol/src/packets/game/c_level_particles.rs new file mode 100755 index 00000000..d700673c --- /dev/null +++ b/azalea-protocol/src/packets/game/c_level_particles.rs @@ -0,0 +1,39 @@ +use azalea_buf::AzBuf; +use azalea_entity::particle::Particle; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundLevelParticles { + pub override_limiter: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub x_dist: f32, + pub y_dist: f32, + pub z_dist: f32, + pub max_speed: f32, + pub count: u32, + pub particle: Particle, +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::AzaleaRead; + + use super::*; + + #[test] + fn test_c_level_particles_packet() { + let slice = &[ + 0, 64, 139, 10, 0, 0, 0, 0, 0, 192, 26, 0, 0, 0, 0, 0, 0, 64, 144, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 63, 128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 63, 128, 0, 0, + ][..]; + let mut bytes = Cursor::new(slice); + + let _packet = ClientboundLevelParticles::azalea_read(&mut bytes).unwrap(); + assert_eq!(bytes.position(), slice.len() as u64); + } +} diff --git a/azalea-protocol/src/packets/game/c_light_update.rs b/azalea-protocol/src/packets/game/c_light_update.rs new file mode 100755 index 00000000..72523291 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_light_update.rs @@ -0,0 +1,22 @@ +use azalea_buf::AzBuf; +use azalea_core::bitset::BitSet; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundLightUpdate { + #[var] + pub x: i32, + #[var] + pub z: i32, + pub light_data: ClientboundLightUpdatePacketData, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct ClientboundLightUpdatePacketData { + pub sky_y_mask: BitSet, + pub block_y_mask: BitSet, + pub empty_sky_y_mask: BitSet, + pub empty_block_y_mask: BitSet, + pub sky_updates: Vec>, + pub block_updates: Vec>, +} diff --git a/azalea-protocol/src/packets/game/c_login.rs b/azalea-protocol/src/packets/game/c_login.rs new file mode 100755 index 00000000..c0616c55 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_login.rs @@ -0,0 +1,27 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +use crate::packets::common::CommonPlayerSpawnInfo; + +/// The first packet sent by the server to the client after login. +/// +/// This packet contains information about the state of the player, the +/// world, and the registry. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundLogin { + pub player_id: u32, + pub hardcore: bool, + pub levels: Vec, + #[var] + pub max_players: i32, + #[var] + pub chunk_radius: u32, + #[var] + pub simulation_distance: u32, + pub reduced_debug_info: bool, + pub show_death_screen: bool, + pub do_limited_crafting: bool, + pub common: CommonPlayerSpawnInfo, + pub enforces_secure_chat: bool, +} diff --git a/azalea-protocol/src/packets/game/c_map_item_data.rs b/azalea-protocol/src/packets/game/c_map_item_data.rs new file mode 100755 index 00000000..9a41ed85 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_map_item_data.rs @@ -0,0 +1,88 @@ +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite}; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, ClientboundGamePacket, AzBuf)] +pub struct ClientboundMapItemData { + #[var] + pub map_id: u32, + pub scale: u8, + pub locked: bool, + pub decorations: Option>, + pub color_patch: OptionalMapPatch, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct MapDecoration { + pub decoration_type: DecorationType, + pub x: i8, + pub y: i8, + /// Minecraft does & 15 on this value, azalea-protocol doesn't. I don't + /// think it matters. + pub rot: i8, + pub name: Option, +} + +#[derive(Debug, Clone)] +pub struct OptionalMapPatch(pub Option); + +impl AzaleaRead for OptionalMapPatch { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + let pos = buf.position(); + Ok(Self(if u8::azalea_read(buf)? == 0 { + None + } else { + buf.set_position(pos); + Some(MapPatch::azalea_read(buf)?) + })) + } +} + +impl AzaleaWrite for OptionalMapPatch { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + match &self.0 { + None => 0u8.azalea_write(buf), + Some(m) => m.azalea_write(buf), + } + } +} + +#[derive(Debug, Clone, AzBuf)] +pub struct MapPatch { + pub width: u8, + pub height: u8, + pub start_x: u8, + pub start_y: u8, + pub map_colors: Vec, +} + +#[derive(Clone, Copy, Debug, AzBuf)] +pub enum DecorationType { + Player, + Frame, + RedMarker, + BlueMarker, + TargetX, + TargetPoint, + PlayerOffMap, + PlayerOffLimits, + Mansion, + Monument, + BannerWhite, + BannerOrange, + BannerMagenta, + BannerLightBlue, + BannerYellow, + BannerLime, + BannerPink, + BannerGray, + BannerLightGray, + BannerCyan, + BannerPurple, + BannerBlue, + BannerBrown, + BannerGreen, + BannerRed, + BannerBlack, + RedX, +} diff --git a/azalea-protocol/src/packets/game/c_merchant_offers.rs b/azalea-protocol/src/packets/game/c_merchant_offers.rs new file mode 100755 index 00000000..e1822579 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_merchant_offers.rs @@ -0,0 +1,30 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMerchantOffers { + #[var] + pub container_id: u32, + pub offers: Vec, + #[var] + pub villager_level: u32, + #[var] + pub villager_xp: u32, + pub show_progress: bool, + pub can_restock: bool, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct MerchantOffer { + pub base_cost_a: ItemStack, + pub result: ItemStack, + pub cost_b: ItemStack, + pub out_of_stock: bool, + pub uses: u32, + pub max_uses: u32, + pub xp: u32, + pub special_price_diff: i32, + pub price_multiplier: f32, + pub demand: u32, +} diff --git a/azalea-protocol/src/packets/game/c_move_entity_pos.rs b/azalea-protocol/src/packets/game/c_move_entity_pos.rs new file mode 100755 index 00000000..b153bb3c --- /dev/null +++ b/azalea-protocol/src/packets/game/c_move_entity_pos.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_core::delta::PositionDelta8; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMoveEntityPos { + #[var] + pub entity_id: u32, + pub delta: PositionDelta8, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs b/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs new file mode 100755 index 00000000..7b22e290 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs @@ -0,0 +1,14 @@ +use azalea_buf::AzBuf; +use azalea_core::delta::PositionDelta8; +use azalea_protocol_macros::ClientboundGamePacket; + +/// This packet is sent by the server when an entity moves less then 8 blocks. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMoveEntityPosRot { + #[var] + pub entity_id: u32, + pub delta: PositionDelta8, + pub y_rot: i8, + pub x_rot: i8, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/c_move_entity_rot.rs b/azalea-protocol/src/packets/game/c_move_entity_rot.rs new file mode 100755 index 00000000..a8362748 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_move_entity_rot.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMoveEntityRot { + #[var] + pub entity_id: u32, + pub y_rot: i8, + pub x_rot: i8, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/c_move_minecart_along_track.rs b/azalea-protocol/src/packets/game/c_move_minecart_along_track.rs new file mode 100644 index 00000000..0a205ddd --- /dev/null +++ b/azalea-protocol/src/packets/game/c_move_minecart_along_track.rs @@ -0,0 +1,19 @@ +use azalea_buf::AzBuf; +use azalea_core::position::Vec3; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMoveMinecartAlongTrack { + #[var] + pub entity_id: u32, + pub lerp_steps: Vec, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct MinecartStep { + pub position: Vec3, + pub movement: Vec3, + pub y_rot: u8, + pub x_rot: u8, + pub weight: f32, +} diff --git a/azalea-protocol/src/packets/game/c_move_vehicle.rs b/azalea-protocol/src/packets/game/c_move_vehicle.rs new file mode 100755 index 00000000..96e3e5c2 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_move_vehicle.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundMoveVehicle { + pub x: f64, + pub y: f64, + pub z: f64, + pub y_rot: f32, + pub x_rot: f32, +} diff --git a/azalea-protocol/src/packets/game/c_open_book.rs b/azalea-protocol/src/packets/game/c_open_book.rs new file mode 100755 index 00000000..2c4f6b15 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_open_book.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::s_interact::InteractionHand; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundOpenBook { + pub hand: InteractionHand, +} diff --git a/azalea-protocol/src/packets/game/c_open_screen.rs b/azalea-protocol/src/packets/game/c_open_screen.rs new file mode 100755 index 00000000..4ba71725 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_open_screen.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundOpenScreen { + #[var] + pub container_id: u32, + pub menu_type: azalea_registry::MenuKind, + pub title: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_open_sign_editor.rs b/azalea-protocol/src/packets/game/c_open_sign_editor.rs new file mode 100755 index 00000000..52f5922c --- /dev/null +++ b/azalea-protocol/src/packets/game/c_open_sign_editor.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundOpenSignEditor { + pub pos: BlockPos, + pub is_front_text: bool, +} diff --git a/azalea-protocol/src/packets/game/c_ping.rs b/azalea-protocol/src/packets/game/c_ping.rs new file mode 100755 index 00000000..956aca8d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_ping.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPing { + pub id: u32, +} diff --git a/azalea-protocol/src/packets/game/c_place_ghost_recipe.rs b/azalea-protocol/src/packets/game/c_place_ghost_recipe.rs new file mode 100755 index 00000000..41c32403 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_place_ghost_recipe.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlaceGhostRecipe { + pub container_id: u8, + pub recipe: ResourceLocation, +} diff --git a/azalea-protocol/src/packets/game/c_player_abilities.rs b/azalea-protocol/src/packets/game/c_player_abilities.rs new file mode 100755 index 00000000..c32a99fe --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_abilities.rs @@ -0,0 +1,53 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, BufReadError}; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::bitset::FixedBitSet; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerAbilities { + pub flags: PlayerAbilitiesFlags, + pub flying_speed: f32, + /// Used for the fov + pub walking_speed: f32, +} + +#[derive(Clone, Debug)] +pub struct PlayerAbilitiesFlags { + pub invulnerable: bool, + pub flying: bool, + pub can_fly: bool, + pub instant_break: bool, +} + +impl AzaleaRead for PlayerAbilitiesFlags { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<4>::azalea_read(buf)?; + Ok(PlayerAbilitiesFlags { + invulnerable: set.index(0), + flying: set.index(1), + can_fly: set.index(2), + instant_break: set.index(3), + }) + } +} + +impl AzaleaWrite for PlayerAbilitiesFlags { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<4>::new(); + if self.invulnerable { + set.set(0); + } + if self.flying { + set.set(1); + } + if self.can_fly { + set.set(2); + } + if self.instant_break { + set.set(3); + } + set.azalea_write(buf) + } +} diff --git a/azalea-protocol/src/packets/game/c_player_chat.rs b/azalea-protocol/src/packets/game/c_player_chat.rs new file mode 100644 index 00000000..0e9960f2 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_chat.rs @@ -0,0 +1,160 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_chat::{ + translatable_component::{StringOrComponent, TranslatableComponent}, + FormattedText, +}; +use azalea_core::bitset::BitSet; +use azalea_crypto::MessageSignature; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::{ChatType, OptionalRegistry}; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket, PartialEq)] +pub struct ClientboundPlayerChat { + pub sender: Uuid, + #[var] + pub index: u32, + pub signature: Option, + pub body: PackedSignedMessageBody, + pub unsigned_content: Option, + pub filter_mask: FilterMask, + pub chat_type: ChatTypeBound, +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct PackedSignedMessageBody { + // the error is here, for some reason it skipped a byte earlier and here + // it's reading `0` when it should be `11` + pub content: String, + pub timestamp: u64, + pub salt: u64, + pub last_seen: PackedLastSeenMessages, +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct PackedLastSeenMessages { + pub entries: Vec, +} + +/// Messages can be deleted by either their signature or message id. +#[derive(Clone, Debug, PartialEq)] +pub enum PackedMessageSignature { + Signature(Box), + Id(u32), +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub enum FilterMask { + PassThrough, + FullyFiltered, + PartiallyFiltered(BitSet), +} + +#[derive(Clone, Debug, PartialEq)] +pub struct ChatTypeBound { + pub chat_type: ChatType, + pub name: FormattedText, + pub target_name: Option, +} +impl AzaleaRead for ChatTypeBound { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let Some(chat_type) = OptionalRegistry::::azalea_read(buf)?.0 else { + return Err(BufReadError::Custom("ChatType cannot be None".to_owned())); + }; + let name = FormattedText::azalea_read(buf)?; + let target_name = Option::::azalea_read(buf)?; + + Ok(ChatTypeBound { + chat_type, + name, + target_name, + }) + } +} +impl AzaleaWrite for ChatTypeBound { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + OptionalRegistry(Some(self.chat_type)).azalea_write(buf)?; + self.name.azalea_write(buf)?; + self.target_name.azalea_write(buf)?; + Ok(()) + } +} + +// must be in Client +#[derive(Clone, Debug, PartialEq)] +pub struct MessageSignatureCache { + pub entries: Vec>, +} + +// impl MessageSignatureCache { +// pub fn unpacker(&self) -> impl Fn(u32) -> Option { + +// } +// } + +// impl PackedSignedMessageBody { +// pub fn unpack(&self, unpacker: impl Fn(u32) -> Option) +// {} } + +impl ClientboundPlayerChat { + /// Returns the content of the message. If you want to get the FormattedText + /// for the whole message including the sender part, use + /// [`ClientboundPlayerChat::message`]. + #[must_use] + pub fn content(&self) -> FormattedText { + self.unsigned_content + .clone() + .unwrap_or_else(|| FormattedText::from(self.body.content.clone())) + } + + /// Get the full message, including the sender part. + #[must_use] + pub fn message(&self) -> FormattedText { + let sender = self.chat_type.name.clone(); + let content = self.content(); + let target = self.chat_type.target_name.clone(); + + let translation_key = self.chat_type.chat_type.chat_translation_key(); + + let mut args = vec![ + StringOrComponent::FormattedText(sender), + StringOrComponent::FormattedText(content), + ]; + if let Some(target) = target { + args.push(StringOrComponent::FormattedText(target)); + } + + let component = TranslatableComponent::new(translation_key.to_string(), args); + + FormattedText::Translatable(component) + } +} + +impl AzaleaRead for PackedMessageSignature { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let id = u32::azalea_read_var(buf)?; + if id == 0 { + let full_signature = MessageSignature::azalea_read(buf)?; + + Ok(PackedMessageSignature::Signature(Box::new(full_signature))) + } else { + Ok(PackedMessageSignature::Id(id - 1)) + } + } +} +impl AzaleaWrite for PackedMessageSignature { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + PackedMessageSignature::Signature(full_signature) => { + 0u32.azalea_write_var(buf)?; + full_signature.azalea_write(buf)?; + } + PackedMessageSignature::Id(id) => { + (id + 1).azalea_write_var(buf)?; + } + } + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/c_player_chat_header.rs b/azalea-protocol/src/packets/game/c_player_chat_header.rs new file mode 100755 index 00000000..d7e84cc5 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_chat_header.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_crypto::{MessageSignature, SignedMessageHeader}; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerChatHeader { + pub header: SignedMessageHeader, + pub header_signature: MessageSignature, + pub body_digest: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_player_combat_end.rs b/azalea-protocol/src/packets/game/c_player_combat_end.rs new file mode 100755 index 00000000..b8029f1b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_combat_end.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +/// Unused by the client in vanilla. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerCombatEnd { + #[var] + pub duration: u32, +} diff --git a/azalea-protocol/src/packets/game/c_player_combat_enter.rs b/azalea-protocol/src/packets/game/c_player_combat_enter.rs new file mode 100755 index 00000000..8c344b49 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_combat_enter.rs @@ -0,0 +1,6 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +/// Unused in vanilla. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerCombatEnter {} diff --git a/azalea-protocol/src/packets/game/c_player_combat_kill.rs b/azalea-protocol/src/packets/game/c_player_combat_kill.rs new file mode 100755 index 00000000..fb7285b5 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_combat_kill.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +/// Used to send a respawn screen. +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerCombatKill { + #[var] + pub player_id: u32, + pub message: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_player_info_remove.rs b/azalea-protocol/src/packets/game/c_player_info_remove.rs new file mode 100644 index 00000000..fcaef9d4 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_info_remove.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerInfoRemove { + pub profile_ids: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_player_info_update.rs b/azalea-protocol/src/packets/game/c_player_info_update.rs new file mode 100644 index 00000000..73c463d5 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_info_update.rs @@ -0,0 +1,326 @@ +use std::{ + collections::HashMap, + io::{Cursor, Write}, +}; + +use azalea_auth::game_profile::{GameProfile, ProfilePropertyValue}; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_chat::FormattedText; +use azalea_core::{bitset::FixedBitSet, game_type::GameMode}; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +use super::s_chat_session_update::RemoteChatSessionData; + +#[derive(Clone, Debug, ClientboundGamePacket)] +pub struct ClientboundPlayerInfoUpdate { + pub actions: ActionEnumSet, + pub entries: Vec, +} + +#[derive(Clone, Debug, Default)] +pub struct PlayerInfoEntry { + pub profile: GameProfile, + pub listed: bool, + pub latency: i32, + pub game_mode: GameMode, + pub display_name: Option, + pub list_order: i32, + pub update_hat: bool, + pub chat_session: Option, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct AddPlayerAction { + pub name: String, + pub properties: HashMap, +} +#[derive(Clone, Debug, AzBuf)] +pub struct InitializeChatAction { + pub chat_session: Option, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateGameModeAction { + pub game_mode: GameMode, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateListedAction { + pub listed: bool, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateLatencyAction { + #[var] + pub latency: i32, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateDisplayNameAction { + pub display_name: Option, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateHatAction { + pub update_hat: bool, +} +#[derive(Clone, Debug, AzBuf)] +pub struct UpdateListOrderAction { + #[var] + pub list_order: i32, +} + +impl AzaleaRead for ClientboundPlayerInfoUpdate { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let actions = ActionEnumSet::azalea_read(buf)?; + let mut entries = Vec::new(); + + let entry_count = u32::azalea_read_var(buf)?; + for _ in 0..entry_count { + let profile_id = Uuid::azalea_read(buf)?; + let mut entry = PlayerInfoEntry::default(); + entry.profile.uuid = profile_id; + + if actions.add_player { + let action = AddPlayerAction::azalea_read(buf)?; + entry.profile.name = action.name; + entry.profile.properties = action.properties; + } + if actions.initialize_chat { + let action = InitializeChatAction::azalea_read(buf)?; + entry.chat_session = action.chat_session; + } + if actions.update_game_mode { + let action = UpdateGameModeAction::azalea_read(buf)?; + entry.game_mode = action.game_mode; + } + if actions.update_listed { + let action = UpdateListedAction::azalea_read(buf)?; + entry.listed = action.listed; + } + if actions.update_latency { + let action = UpdateLatencyAction::azalea_read(buf)?; + entry.latency = action.latency; + } + if actions.update_display_name { + let action = UpdateDisplayNameAction::azalea_read(buf)?; + entry.display_name = action.display_name; + } + if actions.update_hat { + let action = UpdateHatAction::azalea_read(buf)?; + entry.update_hat = action.update_hat; + } + if actions.update_list_order { + let action = UpdateListOrderAction::azalea_read(buf)?; + entry.list_order = action.list_order; + } + + entries.push(entry); + } + + Ok(ClientboundPlayerInfoUpdate { actions, entries }) + } +} + +impl AzaleaWrite for ClientboundPlayerInfoUpdate { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.actions.azalea_write(buf)?; + + (self.entries.len() as u32).azalea_write_var(buf)?; + for entry in &self.entries { + entry.profile.uuid.azalea_write(buf)?; + + if self.actions.add_player { + AddPlayerAction { + name: entry.profile.name.clone(), + properties: entry.profile.properties.clone(), + } + .azalea_write(buf)?; + } + if self.actions.initialize_chat { + InitializeChatAction { + chat_session: entry.chat_session.clone(), + } + .azalea_write(buf)?; + } + if self.actions.update_game_mode { + UpdateGameModeAction { + game_mode: entry.game_mode, + } + .azalea_write(buf)?; + } + if self.actions.update_listed { + UpdateListedAction { + listed: entry.listed, + } + .azalea_write(buf)?; + } + if self.actions.update_latency { + UpdateLatencyAction { + latency: entry.latency, + } + .azalea_write(buf)?; + } + if self.actions.update_display_name { + UpdateDisplayNameAction { + display_name: entry.display_name.clone(), + } + .azalea_write(buf)?; + } + } + + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ActionEnumSet { + pub add_player: bool, + pub initialize_chat: bool, + pub update_game_mode: bool, + pub update_listed: bool, + pub update_latency: bool, + pub update_display_name: bool, + pub update_hat: bool, + pub update_list_order: bool, +} + +impl AzaleaRead for ActionEnumSet { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<7>::azalea_read(buf)?; + Ok(ActionEnumSet { + add_player: set.index(0), + initialize_chat: set.index(1), + update_game_mode: set.index(2), + update_listed: set.index(3), + update_latency: set.index(4), + update_display_name: set.index(5), + update_hat: set.index(6), + update_list_order: set.index(7), + }) + } +} + +impl AzaleaWrite for ActionEnumSet { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<7>::new(); + if self.add_player { + set.set(0); + } + if self.initialize_chat { + set.set(1); + } + if self.update_game_mode { + set.set(2); + } + if self.update_listed { + set.set(3); + } + if self.update_latency { + set.set(4); + } + if self.update_display_name { + set.set(5); + } + if self.update_hat { + set.set(6); + } + if self.update_list_order { + set.set(7); + } + set.azalea_write(buf)?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_action_enum_set() { + let data = ActionEnumSet { + add_player: true, + initialize_chat: false, + update_game_mode: true, + update_listed: false, + update_latency: true, + update_display_name: false, + update_hat: false, + update_list_order: true, + }; + let mut buf = Vec::new(); + data.azalea_write(&mut buf).unwrap(); + let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); + let read_data = ActionEnumSet::azalea_read(&mut data_cursor).unwrap(); + assert_eq!(read_data, data); + } + + #[test] + fn read_player_info_update_packet() { + // from wynncraft + let mut bytes = Cursor::new( + &[ + 63, 1, 196, 217, 99, 243, 221, 101, 79, 183, 167, 88, 48, 71, 25, 49, 5, 142, 5, + 74, 66, 76, 80, 78, 1, 8, 116, 101, 120, 116, 117, 114, 101, 115, 152, 3, 101, 119, + 111, 103, 73, 67, 74, 48, 97, 87, 49, 108, 99, 51, 82, 104, 98, 88, 65, 105, 73, + 68, 111, 103, 77, 84, 99, 119, 77, 106, 99, 49, 78, 106, 89, 48, 77, 68, 81, 120, + 78, 105, 119, 75, 73, 67, 65, 105, 99, 72, 74, 118, 90, 109, 108, 115, 90, 85, 108, + 107, 73, 105, 65, 54, 73, 67, 74, 106, 78, 71, 81, 53, 78, 106, 78, 109, 77, 50, + 82, 107, 78, 106, 85, 48, 90, 109, 73, 51, 89, 84, 99, 49, 79, 68, 77, 119, 78, 68, + 99, 120, 79, 84, 77, 120, 77, 68, 85, 52, 90, 83, 73, 115, 67, 105, 65, 103, 73, + 110, 66, 121, 98, 50, 90, 112, 98, 71, 86, 79, 89, 87, 49, 108, 73, 105, 65, 54, + 73, 67, 74, 75, 81, 107, 120, 81, 84, 105, 73, 115, 67, 105, 65, 103, 73, 110, 78, + 112, 90, 50, 53, 104, 100, 72, 86, 121, 90, 86, 74, 108, 99, 88, 86, 112, 99, 109, + 86, 107, 73, 105, 65, 54, 73, 72, 82, 121, 100, 87, 85, 115, 67, 105, 65, 103, 73, + 110, 82, 108, 101, 72, 82, 49, 99, 109, 86, 122, 73, 105, 65, 54, 73, 72, 115, 75, + 73, 67, 65, 103, 73, 67, 74, 84, 83, 48, 108, 79, 73, 105, 65, 54, 73, 72, 115, 75, + 73, 67, 65, 103, 73, 67, 65, 103, 73, 110, 86, 121, 98, 67, 73, 103, 79, 105, 65, + 105, 97, 72, 82, 48, 99, 68, 111, 118, 76, 51, 82, 108, 101, 72, 82, 49, 99, 109, + 86, 122, 76, 109, 49, 112, 98, 109, 86, 106, 99, 109, 70, 109, 100, 67, 53, 117, + 90, 88, 81, 118, 100, 71, 86, 52, 100, 72, 86, 121, 90, 83, 56, 48, 79, 68, 107, + 120, 89, 84, 107, 50, 89, 84, 74, 107, 77, 84, 103, 120, 78, 84, 69, 49, 79, 68, + 107, 52, 78, 68, 89, 119, 77, 68, 82, 106, 77, 106, 100, 104, 78, 50, 86, 106, 77, + 106, 85, 53, 77, 87, 77, 120, 79, 68, 66, 108, 77, 84, 70, 109, 77, 122, 104, 107, + 89, 122, 69, 52, 77, 84, 74, 109, 77, 106, 100, 104, 77, 71, 82, 108, 78, 50, 69, + 120, 77, 87, 85, 120, 73, 103, 111, 103, 73, 67, 65, 103, 102, 81, 111, 103, 73, + 72, 48, 75, 102, 81, 61, 61, 1, 172, 5, 117, 69, 67, 88, 54, 83, 104, 55, 67, 100, + 87, 49, 77, 99, 78, 88, 122, 72, 73, 105, 90, 86, 43, 103, 111, 121, 47, 120, 53, + 102, 51, 65, 113, 119, 50, 115, 102, 114, 104, 106, 67, 118, 67, 102, 97, 54, 67, + 112, 55, 88, 116, 109, 103, 118, 113, 73, 114, 122, 100, 85, 72, 90, 102, 79, 100, + 100, 112, 109, 87, 70, 110, 70, 119, 97, 85, 109, 97, 76, 106, 86, 102, 121, 88, + 119, 115, 76, 48, 78, 108, 118, 98, 56, 78, 104, 121, 115, 113, 87, 47, 104, 75, + 120, 101, 86, 117, 90, 68, 71, 43, 102, 54, 98, 99, 98, 81, 113, 76, 79, 54, 83, + 66, 88, 111, 81, 74, 85, 104, 74, 66, 90, 102, 88, 78, 53, 51, 100, 102, 80, 98, + 75, 89, 81, 54, 68, 77, 57, 87, 102, 113, 81, 76, 100, 55, 121, 117, 119, 90, 81, + 68, 55, 120, 48, 54, 118, 102, 105, 72, 121, 48, 110, 87, 50, 99, 68, 111, 72, 101, + 71, 102, 72, 67, 53, 104, 52, 112, 84, 109, 65, 101, 100, 101, 109, 116, 48, 67, + 72, 113, 86, 54, 76, 67, 77, 89, 118, 101, 110, 84, 88, 68, 83, 81, 107, 82, 43, + 50, 53, 74, 76, 120, 101, 98, 74, 105, 98, 108, 54, 88, 106, 73, 118, 88, 120, 105, + 87, 68, 121, 85, 49, 65, 43, 121, 48, 79, 104, 53, 89, 115, 116, 121, 86, 116, 106, + 107, 76, 113, 67, 56, 85, 57, 118, 86, 110, 87, 65, 102, 111, 43, 52, 104, 78, 43, + 79, 51, 122, 108, 72, 117, 84, 50, 87, 76, 86, 121, 98, 43, 88, 72, 100, 67, 111, + 111, 88, 75, 82, 75, 83, 86, 71, 101, 122, 103, 75, 78, 47, 53, 65, 53, 67, 119, + 78, 112, 82, 87, 98, 81, 55, 109, 90, 47, 108, 51, 57, 84, 114, 100, 84, 99, 54, + 121, 79, 88, 73, 48, 56, 83, 101, 73, 54, 68, 118, 118, 50, 55, 78, 66, 112, 107, + 47, 97, 72, 119, 65, 49, 116, 105, 78, 108, 55, 122, 49, 103, 97, 79, 107, 113, + 107, 116, 54, 120, 85, 116, 70, 84, 85, 122, 72, 71, 97, 107, 69, 118, 105, 76, 72, + 120, 67, 99, 106, 98, 121, 88, 111, 76, 71, 101, 101, 50, 57, 81, 84, 73, 102, 99, + 97, 69, 56, 104, 108, 110, 73, 97, 74, 111, 115, 72, 117, 57, 116, 100, 54, 52, + 119, 74, 88, 74, 115, 69, 78, 114, 121, 69, 56, 70, 53, 52, 52, 116, 114, 84, 54, + 105, 112, 122, 73, 119, 43, 118, 120, 112, 76, 121, 88, 65, 87, 116, 103, 83, 113, + 76, 108, 107, 121, 78, 50, 77, 115, 57, 74, 89, 110, 100, 79, 111, 90, 57, 77, 53, + 84, 49, 87, 112, 75, 70, 97, 52, 55, 114, 112, 80, 106, 75, 114, 79, 107, 114, 110, + 100, 50, 97, 83, 51, 90, 86, 77, 120, 118, 79, 49, 111, 78, 47, 100, 84, 55, 116, + 77, 119, 82, 52, 109, 97, 55, 85, 73, 68, 50, 48, 84, 113, 105, 83, 75, 56, 108, + 76, 85, 100, 53, 48, 86, 119, 108, 112, 67, 116, 98, 76, 99, 71, 86, 82, 98, 78, + 84, 97, 108, 90, 83, 66, 56, 88, 65, 72, 72, 78, 100, 116, 88, 86, 50, 49, 111, 68, + 77, 116, 77, 122, 79, 104, 82, 109, 43, 57, 88, 81, 90, 79, 50, 55, 66, 69, 71, 65, + 47, 119, 117, 104, 113, 71, 108, 106, 82, 111, 76, 72, 111, 102, 98, 71, 48, 52, + 82, 55, 84, 43, 80, 99, 112, 77, 116, 65, 69, 105, 49, 100, 57, 99, 66, 90, 115, + 119, 84, 105, 107, 113, 114, 89, 49, 86, 49, 48, 106, 104, 77, 76, 118, 99, 99, 78, + 50, 109, 70, 43, 89, 86, 81, 101, 48, 90, 55, 43, 78, 100, 119, 119, 104, 121, 47, + 108, 79, 72, 81, 54, 71, 108, 122, 74, 110, 87, 122, 103, 50, 107, 61, 0, 255, 255, + 255, 255, 15, 1, 255, 255, 255, 255, 15, 1, 10, 8, 0, 4, 116, 101, 120, 116, 0, 0, + 0, + ][..], + ); + let _packet = ClientboundPlayerInfoUpdate::azalea_read(&mut bytes).unwrap(); + } +} diff --git a/azalea-protocol/src/packets/game/c_player_look_at.rs b/azalea-protocol/src/packets/game/c_player_look_at.rs new file mode 100755 index 00000000..4d886814 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_look_at.rs @@ -0,0 +1,24 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerLookAt { + pub from_anchor: Anchor, + pub x: f64, + pub y: f64, + pub z: f64, + pub entity: Option, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Anchor { + Feet = 0, + Eyes = 1, +} + +#[derive(AzBuf, Clone, Debug)] +pub struct AtEntity { + #[var] + pub entity: u32, + pub to_anchor: Anchor, +} diff --git a/azalea-protocol/src/packets/game/c_player_position.rs b/azalea-protocol/src/packets/game/c_player_position.rs new file mode 100755 index 00000000..aa030fc5 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_position.rs @@ -0,0 +1,61 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; +use azalea_core::{bitset::FixedBitSet, position::Vec3}; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerPosition { + #[var] + pub id: u32, + pub pos: Vec3, + pub delta_movement: Vec3, + pub y_rot: f32, + pub x_rot: f32, + pub relative_arguments: RelativeMovements, +} + +#[derive(Debug, Clone)] +pub struct RelativeMovements { + pub x: bool, + pub y: bool, + pub z: bool, + pub y_rot: bool, + pub x_rot: bool, +} + +impl AzaleaRead for RelativeMovements { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + // yes minecraft seriously wastes that many bits, smh + let set = FixedBitSet::<32>::azalea_read(buf)?; + Ok(RelativeMovements { + x: set.index(0), + y: set.index(1), + z: set.index(2), + y_rot: set.index(3), + x_rot: set.index(4), + }) + } +} + +impl AzaleaWrite for RelativeMovements { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<5>::new(); + if self.x { + set.set(0); + } + if self.y { + set.set(1); + } + if self.z { + set.set(2); + } + if self.y_rot { + set.set(3); + } + if self.x_rot { + set.set(4); + } + set.azalea_write(buf) + } +} diff --git a/azalea-protocol/src/packets/game/c_player_rotation.rs b/azalea-protocol/src/packets/game/c_player_rotation.rs new file mode 100755 index 00000000..33214cf9 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_player_rotation.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPlayerRotation { + pub y_rot: f32, + pub x_rot: f32, +} diff --git a/azalea-protocol/src/packets/game/c_pong_response.rs b/azalea-protocol/src/packets/game/c_pong_response.rs new file mode 100755 index 00000000..835666db --- /dev/null +++ b/azalea-protocol/src/packets/game/c_pong_response.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundPongResponse { + pub time: u64, +} diff --git a/azalea-protocol/src/packets/game/c_projectile_power.rs b/azalea-protocol/src/packets/game/c_projectile_power.rs new file mode 100644 index 00000000..8b453ae2 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_projectile_power.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundProjectilePower { + pub id: u32, + pub acceleration_power: f64, +} diff --git a/azalea-protocol/src/packets/game/c_recipe_book_add.rs b/azalea-protocol/src/packets/game/c_recipe_book_add.rs new file mode 100755 index 00000000..e6b91130 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_recipe_book_add.rs @@ -0,0 +1,79 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::c_update_recipes::{Ingredient, SlotDisplayData}; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRecipeBookAdd { + pub entries: Vec, + pub replace: bool, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct Entry { + pub contents: RecipeDisplayEntry, + pub flags: u8, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct RecipeDisplayEntry { + #[var] + pub id: u32, + pub display: RecipeDisplayData, + // ByteBufCodecs.OPTIONAL_VAR_INT + #[var] + pub group: u32, + pub category: azalea_registry::RecipeBookCategory, + pub crafting_requirements: Option>, +} + +/// [`azalea_registry::RecipeDisplay`] +#[derive(Clone, Debug, AzBuf)] +pub enum RecipeDisplayData { + Shapeless(ShapelessCraftingRecipeDisplay), + Shaped(ShapedCraftingRecipeDisplay), + Furnace(FurnaceRecipeDisplay), + Stonecutter(StonecutterRecipeDisplay), + Smithing(SmithingRecipeDisplay), +} + +#[derive(Clone, Debug, AzBuf)] +pub struct ShapelessCraftingRecipeDisplay { + pub ingredients: Vec, + pub result: SlotDisplayData, + pub crafting_station: SlotDisplayData, +} +#[derive(Clone, Debug, AzBuf)] +pub struct ShapedCraftingRecipeDisplay { + #[var] + pub width: u32, + #[var] + pub height: u32, + pub ingredients: Vec, + pub result: SlotDisplayData, + pub crafting_station: SlotDisplayData, +} +#[derive(Clone, Debug, AzBuf)] +pub struct FurnaceRecipeDisplay { + pub ingredient: SlotDisplayData, + pub fuel: SlotDisplayData, + pub result: SlotDisplayData, + pub crafting_station: SlotDisplayData, + #[var] + pub duration: u32, + pub experience: f32, +} +#[derive(Clone, Debug, AzBuf)] +pub struct StonecutterRecipeDisplay { + pub input: SlotDisplayData, + pub result: SlotDisplayData, + pub crafting_station: SlotDisplayData, +} +#[derive(Clone, Debug, AzBuf)] +pub struct SmithingRecipeDisplay { + pub template: SlotDisplayData, + pub base: SlotDisplayData, + pub addition: SlotDisplayData, + pub result: SlotDisplayData, + pub crafting_station: SlotDisplayData, +} diff --git a/azalea-protocol/src/packets/game/c_recipe_book_remove.rs b/azalea-protocol/src/packets/game/c_recipe_book_remove.rs new file mode 100755 index 00000000..aa5a09fe --- /dev/null +++ b/azalea-protocol/src/packets/game/c_recipe_book_remove.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::{c_entity_position_sync::PositionMoveRotation, c_player_position::RelativeMovements}; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRecipeBookRemove { + #[var] + pub id: u32, + pub change: PositionMoveRotation, + pub relatives: RelativeMovements, +} diff --git a/azalea-protocol/src/packets/game/c_recipe_book_settings.rs b/azalea-protocol/src/packets/game/c_recipe_book_settings.rs new file mode 100755 index 00000000..f88a9733 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_recipe_book_settings.rs @@ -0,0 +1,22 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRecipeBookSettings { + pub book_settings: RecipeBookSettings, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct RecipeBookSettings { + pub gui_open: bool, + pub filtering_craftable: bool, + + pub furnace_gui_open: bool, + pub furnace_filtering_craftable: bool, + + pub blast_furnace_gui_open: bool, + pub blast_furnace_filtering_craftable: bool, + + pub smoker_gui_open: bool, + pub smoker_filtering_craftable: bool, +} diff --git a/azalea-protocol/src/packets/game/c_remove_entities.rs b/azalea-protocol/src/packets/game/c_remove_entities.rs new file mode 100755 index 00000000..f3eb7139 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_remove_entities.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRemoveEntities { + #[var] + pub entity_ids: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_remove_mob_effect.rs b/azalea-protocol/src/packets/game/c_remove_mob_effect.rs new file mode 100755 index 00000000..21500db3 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_remove_mob_effect.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRemoveMobEffect { + #[var] + pub entity_id: u32, + pub effect: azalea_registry::MobEffect, +} diff --git a/azalea-protocol/src/packets/game/c_reset_score.rs b/azalea-protocol/src/packets/game/c_reset_score.rs new file mode 100644 index 00000000..8a40dd0d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_reset_score.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundResetScore { + pub owner: String, + pub objective_name: Option, +} diff --git a/azalea-protocol/src/packets/game/c_resource_pack_pop.rs b/azalea-protocol/src/packets/game/c_resource_pack_pop.rs new file mode 100644 index 00000000..14150ea1 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_resource_pack_pop.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundResourcePackPop { + pub id: Option, +} diff --git a/azalea-protocol/src/packets/game/c_resource_pack_push.rs b/azalea-protocol/src/packets/game/c_resource_pack_push.rs new file mode 100644 index 00000000..6e355029 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_resource_pack_push.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundResourcePackPush { + pub id: Uuid, + pub url: String, + pub hash: String, + pub required: bool, + pub prompt: Option, +} diff --git a/azalea-protocol/src/packets/game/c_respawn.rs b/azalea-protocol/src/packets/game/c_respawn.rs new file mode 100755 index 00000000..79bbfd1d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_respawn.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use crate::packets::common::CommonPlayerSpawnInfo; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRespawn { + pub common: CommonPlayerSpawnInfo, + pub data_to_keep: u8, +} diff --git a/azalea-protocol/src/packets/game/c_rotate_head.rs b/azalea-protocol/src/packets/game/c_rotate_head.rs new file mode 100755 index 00000000..26e55948 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_rotate_head.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundRotateHead { + #[var] + pub entity_id: u32, + pub y_head_rot: i8, +} diff --git a/azalea-protocol/src/packets/game/c_section_blocks_update.rs b/azalea-protocol/src/packets/game/c_section_blocks_update.rs new file mode 100755 index 00000000..4554c015 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_section_blocks_update.rs @@ -0,0 +1,43 @@ +use std::io::{Cursor, Write}; + +use azalea_block::BlockState; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; +use azalea_core::position::{ChunkSectionBlockPos, ChunkSectionPos}; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSectionBlocksUpdate { + pub section_pos: ChunkSectionPos, + pub states: Vec, +} + +#[derive(Clone, Debug)] +pub struct BlockStateWithPosition { + pub pos: ChunkSectionBlockPos, + pub state: BlockState, +} + +impl AzaleaRead for BlockStateWithPosition { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let data = u64::azalea_read_var(buf)?; + let position_part = data & 4095; + let state = (data >> 12) as u32; + let state = BlockState::try_from(state) + .map_err(|_| BufReadError::UnexpectedEnumVariant { id: state as i32 })?; + let pos = ChunkSectionBlockPos { + x: (position_part >> 8 & 15) as u8, + y: (position_part & 15) as u8, + z: (position_part >> 4 & 15) as u8, + }; + Ok(BlockStateWithPosition { pos, state }) + } +} + +impl AzaleaWrite for BlockStateWithPosition { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let data = (self.state.id as u64) << 12 + | (u64::from(self.pos.x) << 8 | u64::from(self.pos.z) << 4 | u64::from(self.pos.y)); + u64::azalea_write_var(&data, buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/c_select_advancements_tab.rs b/azalea-protocol/src/packets/game/c_select_advancements_tab.rs new file mode 100755 index 00000000..eb4cc62a --- /dev/null +++ b/azalea-protocol/src/packets/game/c_select_advancements_tab.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSelectAdvancementsTab { + pub tab: Option, +} diff --git a/azalea-protocol/src/packets/game/c_server_data.rs b/azalea-protocol/src/packets/game/c_server_data.rs new file mode 100755 index 00000000..22116685 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_server_data.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundServerData { + pub motd: FormattedText, + pub icon_bytes: Option>, +} diff --git a/azalea-protocol/src/packets/game/c_server_links.rs b/azalea-protocol/src/packets/game/c_server_links.rs new file mode 100644 index 00000000..80c444f0 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_server_links.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +use crate::common::server_links::ServerLinkEntry; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundServerLinks { + pub links: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_set_action_bar_text.rs b/azalea-protocol/src/packets/game/c_set_action_bar_text.rs new file mode 100755 index 00000000..d08c5021 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_action_bar_text.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetActionBarText { + pub text: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_set_border_center.rs b/azalea-protocol/src/packets/game/c_set_border_center.rs new file mode 100755 index 00000000..afc49556 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_border_center.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetBorderCenter { + pub new_center_x: f64, + pub new_center_z: f64, +} diff --git a/azalea-protocol/src/packets/game/c_set_border_lerp_size.rs b/azalea-protocol/src/packets/game/c_set_border_lerp_size.rs new file mode 100755 index 00000000..3c70a40e --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_border_lerp_size.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetBorderLerpSize { + pub old_size: f64, + pub new_size: f64, + #[var] + pub lerp_time: u64, +} diff --git a/azalea-protocol/src/packets/game/c_set_border_size.rs b/azalea-protocol/src/packets/game/c_set_border_size.rs new file mode 100755 index 00000000..6884cde6 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_border_size.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetBorderSize { + pub size: f64, +} diff --git a/azalea-protocol/src/packets/game/c_set_border_warning_delay.rs b/azalea-protocol/src/packets/game/c_set_border_warning_delay.rs new file mode 100755 index 00000000..e1126165 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_border_warning_delay.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetBorderWarningDelay { + #[var] + pub warning_delay: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_border_warning_distance.rs b/azalea-protocol/src/packets/game/c_set_border_warning_distance.rs new file mode 100755 index 00000000..dbb2a742 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_border_warning_distance.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetBorderWarningDistance { + #[var] + pub warning_blocks: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_camera.rs b/azalea-protocol/src/packets/game/c_set_camera.rs new file mode 100755 index 00000000..4ce4547c --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_camera.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetCamera { + #[var] + pub camera_id: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_chunk_cache_center.rs b/azalea-protocol/src/packets/game/c_set_chunk_cache_center.rs new file mode 100755 index 00000000..4c66213c --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_chunk_cache_center.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetChunkCacheCenter { + #[var] + pub x: i32, + #[var] + pub z: i32, +} diff --git a/azalea-protocol/src/packets/game/c_set_chunk_cache_radius.rs b/azalea-protocol/src/packets/game/c_set_chunk_cache_radius.rs new file mode 100755 index 00000000..b992e572 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_chunk_cache_radius.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetChunkCacheRadius { + #[var] + pub radius: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_cursor_item.rs b/azalea-protocol/src/packets/game/c_set_cursor_item.rs new file mode 100644 index 00000000..2c10ae26 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_cursor_item.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetCursorItem { + pub contents: Option, +} diff --git a/azalea-protocol/src/packets/game/c_set_default_spawn_position.rs b/azalea-protocol/src/packets/game/c_set_default_spawn_position.rs new file mode 100755 index 00000000..b6262ac8 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_default_spawn_position.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetDefaultSpawnPosition { + pub pos: BlockPos, + pub angle: f32, +} diff --git a/azalea-protocol/src/packets/game/c_set_display_chat_preview.rs b/azalea-protocol/src/packets/game/c_set_display_chat_preview.rs new file mode 100755 index 00000000..df2a62d4 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_display_chat_preview.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetDisplayChatPreview { + pub enabled: bool, +} diff --git a/azalea-protocol/src/packets/game/c_set_display_objective.rs b/azalea-protocol/src/packets/game/c_set_display_objective.rs new file mode 100755 index 00000000..12118772 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_display_objective.rs @@ -0,0 +1,31 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetDisplayObjective { + pub slot: DisplaySlot, + pub objective_name: String, +} + +#[derive(Clone, Debug, Copy, AzBuf)] +pub enum DisplaySlot { + List = 0, + Sidebar, + BelowName, + TeamBlack, + TeamDarkBlue, + TeamDarkGreen, + TeamDarkAqua, + TeamDarkRed, + TeamDarkPurple, + TeamGold, + TeamGray, + TeamDarkGray, + TeamBlue, + TeamGreen, + TeamAqua, + TeamRed, + TeamLightPurple, + TeamYellow, + TeamWhite, +} diff --git a/azalea-protocol/src/packets/game/c_set_entity_data.rs b/azalea-protocol/src/packets/game/c_set_entity_data.rs new file mode 100755 index 00000000..da6536fe --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_entity_data.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_entity::EntityMetadataItems; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetEntityData { + #[var] + pub id: u32, + pub packed_items: EntityMetadataItems, +} diff --git a/azalea-protocol/src/packets/game/c_set_entity_link.rs b/azalea-protocol/src/packets/game/c_set_entity_link.rs new file mode 100755 index 00000000..c4ce8bdf --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_entity_link.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetEntityLink { + pub source_id: u32, + pub dest_id: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_entity_motion.rs b/azalea-protocol/src/packets/game/c_set_entity_motion.rs new file mode 100755 index 00000000..d0dd7698 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_entity_motion.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetEntityMotion { + #[var] + pub id: u32, + pub xa: i16, + pub ya: i16, + pub za: i16, +} diff --git a/azalea-protocol/src/packets/game/c_set_equipment.rs b/azalea-protocol/src/packets/game/c_set_equipment.rs new file mode 100755 index 00000000..637b2b52 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_equipment.rs @@ -0,0 +1,81 @@ +use std::io::Cursor; + +use azalea_buf::{AzBuf, BufReadError}; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetEquipment { + #[var] + pub entity_id: u32, + pub slots: EquipmentSlots, +} + +#[derive(Clone, Debug)] +pub struct EquipmentSlots { + pub slots: Vec<(EquipmentSlot, ItemStack)>, +} + +impl AzaleaRead for EquipmentSlots { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let mut slots = vec![]; + + loop { + let equipment_byte = u8::azalea_read(buf)?; + let equipment_slot = + EquipmentSlot::from_byte(equipment_byte & 127).ok_or_else(|| { + BufReadError::UnexpectedEnumVariant { + id: equipment_byte.into(), + } + })?; + let item = ItemStack::azalea_read(buf)?; + slots.push((equipment_slot, item)); + if equipment_byte & 128 == 0 { + break; + }; + } + + Ok(EquipmentSlots { slots }) + } +} +impl AzaleaWrite for EquipmentSlots { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + for i in 0..self.slots.len() { + let (equipment_slot, item) = &self.slots[i]; + let mut equipment_byte = *equipment_slot as u8; + if i != self.slots.len() - 1 { + equipment_byte |= 128; + } + equipment_byte.azalea_write(buf)?; + item.azalea_write(buf)?; + } + + Ok(()) + } +} + +#[derive(Clone, Debug, Copy, AzBuf)] +pub enum EquipmentSlot { + MainHand = 0, + OffHand = 1, + Feet = 2, + Legs = 3, + Chest = 4, + Head = 5, +} + +impl EquipmentSlot { + #[must_use] + pub fn from_byte(byte: u8) -> Option { + match byte { + 0 => Some(EquipmentSlot::MainHand), + 1 => Some(EquipmentSlot::OffHand), + 2 => Some(EquipmentSlot::Feet), + 3 => Some(EquipmentSlot::Legs), + 4 => Some(EquipmentSlot::Chest), + 5 => Some(EquipmentSlot::Head), + _ => None, + } + } +} diff --git a/azalea-protocol/src/packets/game/c_set_experience.rs b/azalea-protocol/src/packets/game/c_set_experience.rs new file mode 100755 index 00000000..c11482a0 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_experience.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetExperience { + pub experience_progress: f32, + #[var] + pub experience_level: u32, + #[var] + pub total_experience: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_health.rs b/azalea-protocol/src/packets/game/c_set_health.rs new file mode 100755 index 00000000..56f3fe03 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_health.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetHealth { + pub health: f32, + #[var] + pub food: u32, + pub saturation: f32, +} diff --git a/azalea-protocol/src/packets/game/c_set_held_slot.rs b/azalea-protocol/src/packets/game/c_set_held_slot.rs new file mode 100644 index 00000000..81c21651 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_held_slot.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetHeldSlot { + pub slot: u8, +} diff --git a/azalea-protocol/src/packets/game/c_set_objective.rs b/azalea-protocol/src/packets/game/c_set_objective.rs new file mode 100755 index 00000000..7ddb3f71 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_objective.rs @@ -0,0 +1,82 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite}; +use azalea_chat::{numbers::NumberFormat, FormattedText}; +use azalea_core::objectives::ObjectiveCriteria; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetObjective { + pub objective_name: String, + pub method: Method, +} + +#[derive(Clone, Copy, Debug, AzBuf)] +pub enum MethodKind { + Add, + Remove, + Change, +} + +#[derive(Clone, Debug)] +pub enum Method { + Add { + display_name: FormattedText, + render_type: ObjectiveCriteria, + number_format: NumberFormat, + }, + Remove, + Change { + display_name: FormattedText, + render_type: ObjectiveCriteria, + number_format: NumberFormat, + }, +} + +impl AzaleaRead for Method { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let kind = MethodKind::azalea_read(buf)?; + match kind { + MethodKind::Add => Ok(Method::Add { + display_name: FormattedText::azalea_read(buf)?, + render_type: ObjectiveCriteria::azalea_read(buf)?, + number_format: NumberFormat::azalea_read(buf)?, + }), + MethodKind::Remove => Ok(Method::Remove), + MethodKind::Change => Ok(Method::Change { + display_name: FormattedText::azalea_read(buf)?, + render_type: ObjectiveCriteria::azalea_read(buf)?, + number_format: NumberFormat::azalea_read(buf)?, + }), + } + } +} + +impl AzaleaWrite for Method { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Method::Add { + display_name, + render_type, + number_format, + } => { + MethodKind::Add.azalea_write(buf)?; + display_name.azalea_write(buf)?; + render_type.azalea_write(buf)?; + number_format.azalea_write(buf)?; + } + Method::Remove => MethodKind::Remove.azalea_write(buf)?, + Method::Change { + display_name, + render_type, + number_format, + } => { + MethodKind::Change.azalea_write(buf)?; + display_name.azalea_write(buf)?; + render_type.azalea_write(buf)?; + number_format.azalea_write(buf)?; + } + } + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/c_set_passengers.rs b/azalea-protocol/src/packets/game/c_set_passengers.rs new file mode 100755 index 00000000..76fc3ca0 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_passengers.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetPassengers { + #[var] + pub vehicle: u32, + #[var] + pub passengers: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_set_player_inventory.rs b/azalea-protocol/src/packets/game/c_set_player_inventory.rs new file mode 100644 index 00000000..ca8955ee --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_player_inventory.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetPlayerInventory { + #[var] + pub slot: i32, + pub contents: Option, +} diff --git a/azalea-protocol/src/packets/game/c_set_player_team.rs b/azalea-protocol/src/packets/game/c_set_player_team.rs new file mode 100755 index 00000000..38249cf3 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_player_team.rs @@ -0,0 +1,74 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; +use azalea_chat::{style::ChatFormatting, FormattedText}; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetPlayerTeam { + pub name: String, + pub method: Method, +} + +#[derive(Clone, Debug)] +pub enum Method { + Add((Parameters, PlayerList)), + Remove, + Change(Parameters), + Join(PlayerList), + Leave(PlayerList), +} + +impl AzaleaRead for Method { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + Ok(match u8::azalea_read(buf)? { + 0 => Method::Add((Parameters::azalea_read(buf)?, PlayerList::azalea_read(buf)?)), + 1 => Method::Remove, + 2 => Method::Change(Parameters::azalea_read(buf)?), + 3 => Method::Join(PlayerList::azalea_read(buf)?), + 4 => Method::Leave(PlayerList::azalea_read(buf)?), + id => return Err(BufReadError::UnexpectedEnumVariant { id: i32::from(id) }), + }) + } +} + +impl AzaleaWrite for Method { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Method::Add((parameters, playerlist)) => { + 0u8.azalea_write(buf)?; + parameters.azalea_write(buf)?; + playerlist.azalea_write(buf)?; + } + Method::Remove => { + 1u8.azalea_write(buf)?; + } + Method::Change(parameters) => { + 2u8.azalea_write(buf)?; + parameters.azalea_write(buf)?; + } + Method::Join(playerlist) => { + 3u8.azalea_write(buf)?; + playerlist.azalea_write(buf)?; + } + Method::Leave(playerlist) => { + 4u8.azalea_write(buf)?; + playerlist.azalea_write(buf)?; + } + } + Ok(()) + } +} + +#[derive(AzBuf, Clone, Debug)] +pub struct Parameters { + pub display_name: FormattedText, + pub options: u8, + pub nametag_visibility: String, + pub collision_rule: String, + pub color: ChatFormatting, + pub player_prefix: FormattedText, + pub player_suffix: FormattedText, +} + +type PlayerList = Vec; diff --git a/azalea-protocol/src/packets/game/c_set_score.rs b/azalea-protocol/src/packets/game/c_set_score.rs new file mode 100755 index 00000000..5a16d134 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_score.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_chat::{numbers::NumberFormat, FormattedText}; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetScore { + pub owner: String, + pub objective_name: String, + #[var] + pub score: u32, + pub display: Option, + pub number_format: Option, +} diff --git a/azalea-protocol/src/packets/game/c_set_simulation_distance.rs b/azalea-protocol/src/packets/game/c_set_simulation_distance.rs new file mode 100755 index 00000000..2a80d1f1 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_simulation_distance.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetSimulationDistance { + #[var] + pub simulation_distance: u32, +} diff --git a/azalea-protocol/src/packets/game/c_set_subtitle_text.rs b/azalea-protocol/src/packets/game/c_set_subtitle_text.rs new file mode 100755 index 00000000..31405739 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_subtitle_text.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetSubtitleText { + pub text: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_set_time.rs b/azalea-protocol/src/packets/game/c_set_time.rs new file mode 100755 index 00000000..b1970eec --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_time.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetTime { + pub game_time: u64, + pub day_time: u64, + pub tick_day_time: bool, +} diff --git a/azalea-protocol/src/packets/game/c_set_title_text.rs b/azalea-protocol/src/packets/game/c_set_title_text.rs new file mode 100755 index 00000000..4ef3e590 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_title_text.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetTitleText { + pub text: FormattedText, +} diff --git a/azalea-protocol/src/packets/game/c_set_titles_animation.rs b/azalea-protocol/src/packets/game/c_set_titles_animation.rs new file mode 100755 index 00000000..cc0c37fc --- /dev/null +++ b/azalea-protocol/src/packets/game/c_set_titles_animation.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSetTitlesAnimation { + pub fade_in: u32, + pub stay: u32, + pub fade_out: u32, +} diff --git a/azalea-protocol/src/packets/game/c_sound.rs b/azalea-protocol/src/packets/game/c_sound.rs new file mode 100755 index 00000000..77161769 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_sound.rs @@ -0,0 +1,29 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::SoundEvent; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSound { + pub sound: SoundEvent, + pub source: SoundSource, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, + pub seed: u64, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum SoundSource { + Master = 0, + Music = 1, + Records = 2, + Weather = 3, + Blocks = 4, + Hostile = 5, + Neutral = 6, + Players = 7, + Ambient = 8, + Voice = 9, +} diff --git a/azalea-protocol/src/packets/game/c_sound_entity.rs b/azalea-protocol/src/packets/game/c_sound_entity.rs new file mode 100755 index 00000000..96b22cb8 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_sound_entity.rs @@ -0,0 +1,27 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundSoundEntity { + pub source: SoundSource, + #[var] + pub id: u32, + pub volume: f32, + pub pitch: f32, + #[var] + pub seed: u64, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum SoundSource { + Master = 0, + Music = 1, + Records = 2, + Weather = 3, + Blocks = 4, + Hostile = 5, + Neutral = 6, + Players = 7, + Ambient = 8, + Voice = 9, +} diff --git a/azalea-protocol/src/packets/game/c_start_configuration.rs b/azalea-protocol/src/packets/game/c_start_configuration.rs new file mode 100644 index 00000000..6955b70d --- /dev/null +++ b/azalea-protocol/src/packets/game/c_start_configuration.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundStartConfiguration {} diff --git a/azalea-protocol/src/packets/game/c_stop_sound.rs b/azalea-protocol/src/packets/game/c_stop_sound.rs new file mode 100755 index 00000000..0a01fa71 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_stop_sound.rs @@ -0,0 +1,51 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{BufReadError, AzaleaRead, AzaleaWrite}; +use azalea_core::{bitset::FixedBitSet, resource_location::ResourceLocation}; +use azalea_protocol_macros::ClientboundGamePacket; + +use super::c_sound::SoundSource; + +#[derive(Clone, Debug, ClientboundGamePacket)] +pub struct ClientboundStopSound { + pub source: Option, + pub name: Option, +} + +impl AzaleaRead for ClientboundStopSound { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<2>::azalea_read(buf)?; + let source = if set.index(0) { + Some(SoundSource::azalea_read(buf)?) + } else { + None + }; + let name = if set.index(1) { + Some(ResourceLocation::azalea_read(buf)?) + } else { + None + }; + + Ok(Self { source, name }) + } +} + +impl AzaleaWrite for ClientboundStopSound { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<2>::new(); + if self.source.is_some() { + set.set(0); + } + if self.name.is_some() { + set.set(1); + } + set.azalea_write(buf)?; + if let Some(source) = &self.source { + source.azalea_write(buf)?; + } + if let Some(name) = &self.name { + name.azalea_write(buf)?; + } + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/c_store_cookie.rs b/azalea-protocol/src/packets/game/c_store_cookie.rs new file mode 100644 index 00000000..a1deee4f --- /dev/null +++ b/azalea-protocol/src/packets/game/c_store_cookie.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundStoreCookie { + pub key: ResourceLocation, + pub payload: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_system_chat.rs b/azalea-protocol/src/packets/game/c_system_chat.rs new file mode 100755 index 00000000..14dfdcbf --- /dev/null +++ b/azalea-protocol/src/packets/game/c_system_chat.rs @@ -0,0 +1,45 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket, PartialEq)] +pub struct ClientboundSystemChat { + pub content: FormattedText, + pub overlay: bool, +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::AzaleaRead; + + use super::*; + + #[test] + fn test_c_system_chat_packet() { + #[rustfmt::skip] + let bytes = [ + 10, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 2, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 3, 112, 121, 53, 11, 0, 2, 105, 100, 0, 0, 0, 4, 101, 54, 191, 237, 134, 149, 72, 253, 131, 161, 236, 210, 76, 242, 160, 253, 8, 0, 4, 116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108, 97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111, 119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69, 118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103, 101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117, 101, 0, 10, 47, 116, 101, 108, 108, 32, 112, 121, 53, 32, 0, 8, 0, 9, 105, 110, 115, 101, 114, 116, 105, 111, 110, 0, 3, 112, 121, 53, 8, 0, 4, 116, 101, 120, 116, 0, 3, 112, 121, 53, 0, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 1, 0, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 2, 105, 100, 0, 25, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 100, 105, 97, 109, 111, 110, 100, 95, 112, 105, 99, 107, 97, 120, 101, 8, 0, 3, 116, 97, 103, 0, 10, 123, 68, 97, 109, 97, 103, 101, 58, 48, 125, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 9, 115, 104, 111, 119, 95, 105, 116, 101, 109, 0, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 1, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 1, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 30, 105, 116, 101, 109, 46, 109, 105, 110, 101, 99, 114, 97, 102, 116, 46, 100, 105, 97, 109, 111, 110, 100, 95, 112, 105, 99, 107, 97, 120, 101, 0, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 119, 104, 105, 116, 101, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 20, 99, 104, 97, 116, 46, 115, 113, 117, 97, 114, 101, 95, 98, 114, 97, 99, 107, 101, 116, 115, 0, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 3, 112, 121, 53, 11, 0, 2, 105, 100, 0, 0, 0, 4, 101, 54, 191, 237, 134, 149, 72, 253, 131, 161, 236, 210, 76, 242, 160, 253, 8, 0, 4, 116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108, 97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111, 119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69, 118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103, 101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117, 101, 0, 10, 47, 116, 101, 108, 108, 32, 112, 121, 53, 32, 0, 8, 0, 9, 105, 110, 115, 101, 114, 116, 105, 111, 110, 0, 3, 112, 121, 53, 8, 0, 4, 116, 101, 120, 116, 0, 3, 112, 121, 53, 0, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 28, 99, 111, 109, 109, 97, 110, 100, 115, 46, 103, 105, 118, 101, 46, 115, 117, 99, 99, 101, 115, 115, 46, 115, 105, 110, 103, 108, 101, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 114, 97, 121, 1, 0, 6, 105, 116, 97, 108, 105, 99, 1, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 15, 99, 104, 97, 116, 46, 116, 121, 112, 101, 46, 97, 100, 109, 105, 110, 0, 0 + ]; + + let packet = ClientboundSystemChat::azalea_read(&mut Cursor::new(&bytes)).unwrap(); + assert_eq!( + packet.content.to_string(), + "[py5: Gave 1 [Diamond Pickaxe] to py5]".to_string() + ); + } + + #[test] + fn test_translate_with_string_array_c_system_chat_packet() { + #[rustfmt::skip] + let bytes = [ + 10, 9, 0, 4, 119, 105, 116, 104, 8, 0, 0, 0, 1, 0, 14, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 100, 117, 115, 116, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 25, 99, 111, 109, 109, 97, 110, 100, 115, 46, 112, 97, 114, 116, 105, 99, 108, 101, 46, 115, 117, 99, 99, 101, 115, 115, 0, 0 + ]; + let packet = ClientboundSystemChat::azalea_read(&mut Cursor::new(&bytes)).unwrap(); + assert_eq!( + packet.content.to_string(), + "Displaying particle minecraft:dust".to_string() + ); + } +} diff --git a/azalea-protocol/src/packets/game/c_tab_list.rs b/azalea-protocol/src/packets/game/c_tab_list.rs new file mode 100755 index 00000000..268351da --- /dev/null +++ b/azalea-protocol/src/packets/game/c_tab_list.rs @@ -0,0 +1,28 @@ +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTabList { + pub header: FormattedText, + pub footer: FormattedText, +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::AzaleaRead; + + use super::*; + + #[test] + fn test_packet_from_viaversion() { + #[rustfmt::skip] + let mut bytes = Cursor::new(&[ + 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 3, 1, 0, 4, 98, 111, 108, 100, 1, 8, 0, 4, 116, 101, 120, 116, 0, 16, 50, 66, 85, 73, 76, 68, 69, 82, 83, 50, 84, 79, 79, 76, 83, 10, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 114, 97, 121, 0, 8, 0, 0, 0, 1, 10, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 27, 80, 101, 110, 100, 105, 110, 103, 32, 99, 111, 110, 110, 101, 99, 116, 105, 111, 110, 32, 116, 111, 32, 50, 98, 50, 116, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0, 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 1, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 72, 84, 104, 105, 115, 32, 97, 99, 99, 111, 117, 110, 116, 32, 104, 97, 115, 32, 112, 114, 105, 111, 114, 105, 116, 121, 32, 115, 116, 97, 116, 117, 115, 32, 97, 110, 100, 32, 119, 105, 108, 108, 32, 98, 101, 32, 112, 108, 97, 99, 101, 100, 32, 105, 110, 32, 97, 32, 115, 104, 111, 114, 116, 101, 114, 32, 113, 117, 101, 117, 101, 46, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0 + ][..]); + let _packet = ClientboundTabList::azalea_read(&mut bytes).unwrap(); + assert!(bytes.get_ref()[bytes.position() as usize..].is_empty()); + } +} diff --git a/azalea-protocol/src/packets/game/c_tag_query.rs b/azalea-protocol/src/packets/game/c_tag_query.rs new file mode 100755 index 00000000..efd94e32 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_tag_query.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use simdnbt::owned::NbtTag; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTagQuery { + #[var] + pub transaction_id: u32, + pub tag: NbtTag, +} diff --git a/azalea-protocol/src/packets/game/c_take_item_entity.rs b/azalea-protocol/src/packets/game/c_take_item_entity.rs new file mode 100755 index 00000000..0dfc8552 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_take_item_entity.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTakeItemEntity { + #[var] + pub item_id: u32, + #[var] + pub player_id: u32, + #[var] + pub amount: u32, +} diff --git a/azalea-protocol/src/packets/game/c_teleport_entity.rs b/azalea-protocol/src/packets/game/c_teleport_entity.rs new file mode 100755 index 00000000..0f026133 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_teleport_entity.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_core::position::Vec3; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTeleportEntity { + #[var] + pub id: u32, + pub position: Vec3, + pub y_rot: i8, + pub x_rot: i8, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/c_ticking_state.rs b/azalea-protocol/src/packets/game/c_ticking_state.rs new file mode 100644 index 00000000..3e4e11c2 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_ticking_state.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTickingState { + pub tick_rate: f32, + pub is_frozen: bool, +} diff --git a/azalea-protocol/src/packets/game/c_ticking_step.rs b/azalea-protocol/src/packets/game/c_ticking_step.rs new file mode 100644 index 00000000..0a151134 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_ticking_step.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTickingStep { + #[var] + pub tick_steps: u32, +} diff --git a/azalea-protocol/src/packets/game/c_transfer.rs b/azalea-protocol/src/packets/game/c_transfer.rs new file mode 100644 index 00000000..ad7de333 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_transfer.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundTransfer { + pub host: String, + #[var] + pub port: u32, +} diff --git a/azalea-protocol/src/packets/game/c_update_advancements.rs b/azalea-protocol/src/packets/game/c_update_advancements.rs new file mode 100755 index 00000000..cd0c0b98 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_advancements.rs @@ -0,0 +1,205 @@ +use std::collections::HashMap; +use std::io::Cursor; + +use azalea_buf::AzBuf; +use azalea_chat::FormattedText; +use azalea_core::resource_location::ResourceLocation; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateAdvancements { + pub reset: bool, + pub added: Vec, + pub removed: Vec, + pub progress: HashMap, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct Advancement { + pub parent_id: Option, + pub display: Option, + pub requirements: Vec>, + pub sends_telemetry_event: bool, +} + +#[derive(Clone, Debug)] +pub struct DisplayInfo { + pub title: FormattedText, + pub description: FormattedText, + pub icon: ItemStack, + pub frame: FrameType, + pub show_toast: bool, + pub hidden: bool, + pub background: Option, + pub x: f32, + pub y: f32, +} + +impl azalea_buf::AzaleaWrite for DisplayInfo { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + self.title.azalea_write(buf)?; + self.description.azalea_write(buf)?; + self.icon.azalea_write(buf)?; + self.frame.azalea_write(buf)?; + + let mut data: u32 = 0; + if self.background.is_some() { + data |= 0b001; + } + if self.show_toast { + data |= 0b010; + } + if self.hidden { + data |= 0b100; + } + data.azalea_write(buf)?; + + if let Some(background) = &self.background { + background.azalea_write(buf)?; + } + self.x.azalea_write(buf)?; + self.y.azalea_write(buf)?; + Ok(()) + } +} +impl azalea_buf::AzaleaRead for DisplayInfo { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let title = azalea_buf::AzaleaRead::azalea_read(buf)?; + let description = azalea_buf::AzaleaRead::azalea_read(buf)?; + let icon = azalea_buf::AzaleaRead::azalea_read(buf)?; + let frame = azalea_buf::AzaleaRead::azalea_read(buf)?; + + let data = u32::azalea_read(buf)?; + let has_background = (data & 0b1) != 0; + let show_toast = (data & 0b10) != 0; + let hidden = (data & 0b100) != 0; + + let background = if has_background { + Some(ResourceLocation::azalea_read(buf)?) + } else { + None + }; + let x = azalea_buf::AzaleaRead::azalea_read(buf)?; + let y = azalea_buf::AzaleaRead::azalea_read(buf)?; + Ok(DisplayInfo { + title, + description, + icon, + frame, + show_toast, + hidden, + background, + x, + y, + }) + } +} + +#[derive(Clone, Debug, Copy, AzBuf)] +pub enum FrameType { + Task = 0, + Challenge = 1, + Goal = 2, +} + +pub type AdvancementProgress = HashMap; + +#[derive(Clone, Debug, AzBuf)] +pub struct CriterionProgress { + pub date: Option, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct AdvancementHolder { + pub id: ResourceLocation, + pub value: Advancement, +} + +#[cfg(test)] +mod tests { + use azalea_buf::{AzaleaRead, AzaleaWrite}; + + use super::*; + + #[test] + fn test() { + let packet = ClientboundUpdateAdvancements { + reset: true, + added: [AdvancementHolder { + id: ResourceLocation::new("minecraft:test"), + value: Advancement { + parent_id: None, + display: Some(DisplayInfo { + title: FormattedText::from("title".to_string()), + description: FormattedText::from("description".to_string()), + icon: ItemStack::Empty, + frame: FrameType::Task, + show_toast: true, + hidden: false, + background: None, + x: 0.0, + y: 0.0, + }), + requirements: Vec::new(), + sends_telemetry_event: false, + }, + }] + .into_iter() + .collect(), + removed: vec![ResourceLocation::new("minecraft:test2")], + progress: [( + ResourceLocation::new("minecraft:test3"), + [( + "minecraft:test4".to_string(), + CriterionProgress { + date: Some(123456789), + }, + )] + .into_iter() + .collect(), + )] + .into_iter() + .collect(), + }; + + let mut data = Vec::new(); + packet.azalea_write(&mut data).unwrap(); + let mut buf: Cursor<&[u8]> = Cursor::new(&data); + + let read_packet = ClientboundUpdateAdvancements::azalea_read(&mut buf).unwrap(); + assert_eq!(packet.reset, read_packet.reset); + assert_eq!(packet.removed, read_packet.removed); + + let advancement = packet + .added + .into_iter() + .find_map(|a| { + if a.id == ResourceLocation::new("minecraft:test") { + Some(a.value) + } else { + None + } + }) + .unwrap() + .clone(); + let read_advancement = read_packet + .added + .into_iter() + .find_map(|a| { + if a.id == ResourceLocation::new("minecraft:test") { + Some(a.value) + } else { + None + } + }) + .unwrap() + .clone(); + assert_eq!(advancement.parent_id, read_advancement.parent_id); + + let display = advancement.display.unwrap(); + let read_display = read_advancement.display.unwrap(); + assert_eq!(display.title, read_display.title); + assert_eq!(display.description, read_display.description); + } +} diff --git a/azalea-protocol/src/packets/game/c_update_attributes.rs b/azalea-protocol/src/packets/game/c_update_attributes.rs new file mode 100755 index 00000000..2b800643 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_attributes.rs @@ -0,0 +1,18 @@ +use azalea_buf::AzBuf; +use azalea_entity::attributes::AttributeModifier; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::Attribute; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateAttributes { + #[var] + pub entity_id: u32, + pub values: Vec, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct AttributeSnapshot { + pub attribute: Attribute, + pub base: f64, + pub modifiers: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_update_enabled_features.rs b/azalea-protocol/src/packets/game/c_update_enabled_features.rs new file mode 100644 index 00000000..d4dac483 --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_enabled_features.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateEnabledFeatures { + pub features: Vec, +} diff --git a/azalea-protocol/src/packets/game/c_update_mob_effect.rs b/azalea-protocol/src/packets/game/c_update_mob_effect.rs new file mode 100755 index 00000000..6a31ccab --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_mob_effect.rs @@ -0,0 +1,15 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::MobEffect; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateMobEffect { + #[var] + pub entity_id: u32, + pub mob_effect: MobEffect, + #[var] + pub effect_amplifier: u32, + #[var] + pub effect_duration_ticks: u32, + pub flags: u8, +} diff --git a/azalea-protocol/src/packets/game/c_update_recipes.rs b/azalea-protocol/src/packets/game/c_update_recipes.rs new file mode 100755 index 00000000..38c4f37b --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_recipes.rs @@ -0,0 +1,74 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ClientboundGamePacket; +use azalea_registry::HolderSet; + +#[derive(Clone, Debug, PartialEq, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateRecipes { + pub item_sets: HashMap, + pub stonecutter_recipes: Vec, +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct SingleInputEntry { + pub input: Ingredient, + pub recipe: SelectableRecipe, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct SelectableRecipe { + pub option_display: SlotDisplayData, +} + +/// [`azalea_registry::SlotDisplay`] +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub enum SlotDisplayData { + Empty, + AnyFuel, + Item(ItemStackDisplay), + ItemStack(ItemStackSlotDisplay), + Tag(ResourceLocation), + SmithingTrim(Box), + WithRemainder(Box), + Composite(CompositeSlotDisplay), +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct ItemStackDisplay { + pub item: azalea_registry::Item, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct ItemStackSlotDisplay { + pub stack: ItemStack, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct TagSlotDisplay { + pub tag: azalea_registry::Item, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct SmithingTrimDemoSlotDisplay { + pub base: SlotDisplayData, + pub material: SlotDisplayData, + pub pattern: SlotDisplayData, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct WithRemainderSlotDisplay { + pub input: SlotDisplayData, + pub remainder: SlotDisplayData, +} +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct CompositeSlotDisplay { + pub contents: Vec, +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct RecipePropertySet { + pub items: Vec, +} + +#[derive(Clone, Debug, PartialEq, AzBuf)] +pub struct Ingredient { + pub allowed: HolderSet, +} diff --git a/azalea-protocol/src/packets/game/c_update_tags.rs b/azalea-protocol/src/packets/game/c_update_tags.rs new file mode 100755 index 00000000..4b63ec8f --- /dev/null +++ b/azalea-protocol/src/packets/game/c_update_tags.rs @@ -0,0 +1,74 @@ +use std::io::Cursor; +use std::ops::Deref; +use std::{collections::HashMap, io::Write}; + +use azalea_buf::{AzBuf, AzaleaReadVar, AzaleaWriteVar, BufReadError}; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] +pub struct ClientboundUpdateTags { + pub tags: TagMap, +} + +#[derive(Clone, Debug)] +pub struct Tags { + pub name: ResourceLocation, + pub elements: Vec, +} + +#[derive(Clone, Debug)] +pub struct TagMap(pub HashMap>); + +impl AzaleaRead for TagMap { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let length = u32::azalea_read_var(buf)? as usize; + let mut data = HashMap::with_capacity(length); + for _ in 0..length { + let tag_type = ResourceLocation::azalea_read(buf)?; + let tags_count = i32::azalea_read_var(buf)? as usize; + let mut tags_vec = Vec::with_capacity(tags_count); + for _ in 0..tags_count { + let tags = Tags::azalea_read(buf)?; + tags_vec.push(tags); + } + data.insert(tag_type, tags_vec); + } + Ok(TagMap(data)) + } +} + +impl AzaleaWrite for TagMap { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.len() as u32).azalea_write_var(buf)?; + for (k, v) in &self.0 { + k.azalea_write(buf)?; + v.azalea_write(buf)?; + } + Ok(()) + } +} +impl AzaleaRead for Tags { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let name = ResourceLocation::azalea_read(buf)?; + let elements = Vec::::azalea_read_var(buf)?; + Ok(Tags { name, elements }) + } +} + +impl AzaleaWrite for Tags { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.name.azalea_write(buf)?; + self.elements.azalea_write_var(buf)?; + Ok(()) + } +} + +impl Deref for TagMap { + type Target = HashMap>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs deleted file mode 100755 index 6b62df19..00000000 --- a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs +++ /dev/null @@ -1,37 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::{position::Vec3, resource_location::ResourceLocation}; -use azalea_entity::{metadata::apply_default_metadata, EntityBundle}; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundAddEntityPacket { - /// The id of the entity. - #[var] - pub id: u32, - pub uuid: Uuid, - pub entity_type: azalea_registry::EntityKind, - pub position: Vec3, - pub x_rot: i8, - pub y_rot: i8, - pub y_head_rot: i8, - #[var] - pub data: u32, - pub x_vel: i16, - pub y_vel: i16, - pub z_vel: i16, -} - -impl ClientboundAddEntityPacket { - /// Make the entity into a bundle that can be inserted into the ECS. You - /// must apply the metadata after inserting the bundle with - /// [`Self::apply_metadata`]. - pub fn as_entity_bundle(&self, world_name: ResourceLocation) -> EntityBundle { - EntityBundle::new(self.uuid, self.position, self.entity_type, world_name) - } - - /// Apply the default metadata for the given entity. - pub fn apply_metadata(&self, entity: &mut bevy_ecs::system::EntityCommands) { - apply_default_metadata(entity, self.entity_type); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_add_experience_orb_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_experience_orb_packet.rs deleted file mode 100755 index 84edcae6..00000000 --- a/azalea-protocol/src/packets/game/clientbound_add_experience_orb_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundAddExperienceOrbPacket { - #[var] - pub id: u32, - pub x: f64, - pub y: f64, - pub z: f64, - pub value: u16, -} diff --git a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs deleted file mode 100755 index 45ab4584..00000000 --- a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs +++ /dev/null @@ -1,27 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::{ResourceLocation, Vec3}; -use azalea_entity::{metadata::PlayerMetadataBundle, EntityBundle, PlayerBundle}; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::EntityKind; -use uuid::Uuid; - -/// This packet is sent by the server when a player comes into visible range, -/// not when a player joins. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundAddPlayerPacket { - #[var] - pub id: u32, - pub uuid: Uuid, - pub position: Vec3, - pub x_rot: i8, - pub y_rot: i8, -} - -impl ClientboundAddPlayerPacket { - pub fn as_player_bundle(&self, world_name: ResourceLocation) -> PlayerBundle { - PlayerBundle { - entity: EntityBundle::new(self.uuid, self.position, EntityKind::Player, world_name), - metadata: PlayerMetadataBundle::default(), - } - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs b/azalea-protocol/src/packets/game/clientbound_animate_packet.rs deleted file mode 100755 index 8c99b1b7..00000000 --- a/azalea-protocol/src/packets/game/clientbound_animate_packet.rs +++ /dev/null @@ -1,21 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundAnimatePacket { - #[var] - pub id: u32, - pub action: AnimationAction, -} - -// minecraft actually uses a u8 for this, but a varint still works and makes it -// so i don't have to add a special handler -#[derive(Clone, Debug, Copy, McBuf)] -pub enum AnimationAction { - SwingMainHand = 0, - Hurt = 1, - WakeUp = 2, - SwingOffHand = 3, - CriticalHit = 4, - MagicCriticalHit = 5, -} diff --git a/azalea-protocol/src/packets/game/clientbound_award_stats_packet.rs b/azalea-protocol/src/packets/game/clientbound_award_stats_packet.rs deleted file mode 100755 index 32e2c8aa..00000000 --- a/azalea-protocol/src/packets/game/clientbound_award_stats_packet.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::collections::HashMap; - -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundAwardStatsPacket { - #[var] - pub stats: HashMap, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, McBuf)] -pub enum Stat { - Mined(azalea_registry::Block), - Crafted(azalea_registry::Item), - Used(azalea_registry::Item), - Broken(azalea_registry::Item), - PickedUp(azalea_registry::Item), - Dropped(azalea_registry::Item), - Killed(azalea_registry::EntityKind), - KilledBy(azalea_registry::EntityKind), - Custom(azalea_registry::CustomStat), -} diff --git a/azalea-protocol/src/packets/game/clientbound_block_changed_ack_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_changed_ack_packet.rs deleted file mode 100755 index e9e57c8d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_block_changed_ack_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBlockChangedAckPacket { - #[var] - pub sequence: i32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_block_destruction_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_destruction_packet.rs deleted file mode 100755 index 130c698e..00000000 --- a/azalea-protocol/src/packets/game/clientbound_block_destruction_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBlockDestructionPacket { - /// The ID of the entity breaking the block. - #[var] - pub id: u32, - pub pos: BlockPos, - /// 0–9 to set it, any other value to remove it. - pub progress: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_block_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_entity_data_packet.rs deleted file mode 100755 index 3406a75f..00000000 --- a/azalea-protocol/src/packets/game/clientbound_block_entity_data_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; -use simdnbt::owned::Nbt; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBlockEntityDataPacket { - pub pos: BlockPos, - pub block_entity_type: azalea_registry::BlockEntityKind, - pub tag: Nbt, -} diff --git a/azalea-protocol/src/packets/game/clientbound_block_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_event_packet.rs deleted file mode 100755 index 86f57b97..00000000 --- a/azalea-protocol/src/packets/game/clientbound_block_event_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::Block; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBlockEventPacket { - pub pos: BlockPos, - pub action_id: u8, - pub action_parameter: u8, - pub block: Block, -} diff --git a/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs deleted file mode 100755 index c1869e74..00000000 --- a/azalea-protocol/src/packets/game/clientbound_block_update_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_block::BlockState; -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBlockUpdatePacket { - pub pos: BlockPos, - pub block_state: BlockState, -} diff --git a/azalea-protocol/src/packets/game/clientbound_boss_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_boss_event_packet.rs deleted file mode 100755 index 65240edf..00000000 --- a/azalea-protocol/src/packets/game/clientbound_boss_event_packet.rs +++ /dev/null @@ -1,145 +0,0 @@ -use std::io::Cursor; -use std::io::Write; - -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_chat::FormattedText; -use azalea_core::bitset::FixedBitSet; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBossEventPacket { - pub id: Uuid, - pub operation: Operation, -} - -#[derive(Clone, Debug)] -pub enum Operation { - Add(AddOperation), - Remove, - UpdateProgress(f32), - UpdateName(FormattedText), - UpdateStyle(Style), - UpdateProperties(Properties), -} - -impl McBufReadable for Operation { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let operation_id = u32::var_read_from(buf)?; - Ok(match operation_id { - 0 => Operation::Add(AddOperation::read_from(buf)?), - 1 => Operation::Remove, - 2 => Operation::UpdateProgress(f32::read_from(buf)?), - 3 => Operation::UpdateName(FormattedText::read_from(buf)?), - 4 => Operation::UpdateStyle(Style::read_from(buf)?), - 5 => Operation::UpdateProperties(Properties::read_from(buf)?), - _ => { - return Err(BufReadError::UnexpectedEnumVariant { - id: operation_id as i32, - }) - } - }) - } -} - -impl McBufWritable for Operation { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - Operation::Add(add) => { - 0u32.var_write_into(buf)?; - add.write_into(buf)?; - } - Operation::Remove => { - 1u32.var_write_into(buf)?; - } - Operation::UpdateProgress(progress) => { - 2u32.var_write_into(buf)?; - progress.write_into(buf)?; - } - Operation::UpdateName(name) => { - 3u32.var_write_into(buf)?; - name.write_into(buf)?; - } - Operation::UpdateStyle(style) => { - 4u32.var_write_into(buf)?; - style.write_into(buf)?; - } - Operation::UpdateProperties(properties) => { - 5u32.var_write_into(buf)?; - properties.write_into(buf)?; - } - } - Ok(()) - } -} - -#[derive(Clone, Debug, McBuf)] -pub struct AddOperation { - pub name: FormattedText, - pub progress: f32, - pub style: Style, - pub properties: Properties, -} - -#[derive(Clone, Debug, McBuf)] -pub struct Style { - pub color: BossBarColor, - pub overlay: BossBarOverlay, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum BossBarColor { - Pink = 0, - Blue = 1, - Red = 2, - Green = 3, - Yellow = 4, - Purple = 5, - White = 6, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum BossBarOverlay { - Progress = 0, - Notched6 = 1, - Notched10 = 2, - Notched12 = 3, - Notched20 = 4, -} - -#[derive(Clone, Debug)] -pub struct Properties { - pub darken_screen: bool, - pub play_music: bool, - pub create_world_fog: bool, -} - -impl McBufReadable for Properties { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<3>::read_from(buf)?; - Ok(Self { - darken_screen: set.index(0), - play_music: set.index(1), - create_world_fog: set.index(2), - }) - } -} - -impl McBufWritable for Properties { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<3>::new(); - if self.darken_screen { - set.set(0); - } - if self.play_music { - set.set(1); - } - if self.create_world_fog { - set.set(2); - } - set.write_into(buf)?; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_bundle_packet.rs b/azalea-protocol/src/packets/game/clientbound_bundle_packet.rs deleted file mode 100644 index cad2eca3..00000000 --- a/azalea-protocol/src/packets/game/clientbound_bundle_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundBundlePacket {} diff --git a/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs b/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs deleted file mode 100755 index e7dafbeb..00000000 --- a/azalea-protocol/src/packets/game/clientbound_change_difficulty_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::difficulty::Difficulty; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundChangeDifficultyPacket { - pub difficulty: Difficulty, - pub locked: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_chat_preview_packet.rs b/azalea-protocol/src/packets/game/clientbound_chat_preview_packet.rs deleted file mode 100755 index 40f28259..00000000 --- a/azalea-protocol/src/packets/game/clientbound_chat_preview_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundChatPreviewPacket { - pub query_id: i32, - pub preview: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_chunk_batch_finished_packet.rs b/azalea-protocol/src/packets/game/clientbound_chunk_batch_finished_packet.rs deleted file mode 100644 index 27bc2f25..00000000 --- a/azalea-protocol/src/packets/game/clientbound_chunk_batch_finished_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundChunkBatchFinishedPacket { - #[var] - pub batch_size: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_chunk_batch_start_packet.rs b/azalea-protocol/src/packets/game/clientbound_chunk_batch_start_packet.rs deleted file mode 100644 index 308ba8c9..00000000 --- a/azalea-protocol/src/packets/game/clientbound_chunk_batch_start_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundChunkBatchStartPacket {} diff --git a/azalea-protocol/src/packets/game/clientbound_chunks_biomes_packet.rs b/azalea-protocol/src/packets/game/clientbound_chunks_biomes_packet.rs deleted file mode 100644 index 7c8f2154..00000000 --- a/azalea-protocol/src/packets/game/clientbound_chunks_biomes_packet.rs +++ /dev/null @@ -1,14 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::ChunkPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundChunksBiomesPacket { - pub chunk_biome_data: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct ChunkBiomeData { - pub pos: ChunkPos, - pub buffer: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_clear_titles_packet.rs b/azalea-protocol/src/packets/game/clientbound_clear_titles_packet.rs deleted file mode 100644 index 3bdc0c79..00000000 --- a/azalea-protocol/src/packets/game/clientbound_clear_titles_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundClearTitlesPacket { - pub reset_times: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_command_suggestions_packet.rs b/azalea-protocol/src/packets/game/clientbound_command_suggestions_packet.rs deleted file mode 100755 index c9752ee9..00000000 --- a/azalea-protocol/src/packets/game/clientbound_command_suggestions_packet.rs +++ /dev/null @@ -1,37 +0,0 @@ -use azalea_brigadier::suggestion::Suggestions; -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCommandSuggestionsPacket { - #[var] - pub id: u32, - pub suggestions: Suggestions, -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use azalea_brigadier::{context::StringRange, suggestion::Suggestion}; - use azalea_buf::{McBufReadable, McBufWritable}; - - use super::*; - - #[test] - fn test_suggestions() { - let suggestions = Suggestions::new( - StringRange::new(0, 5), - vec![Suggestion::new_with_tooltip( - StringRange::new(1, 4), - "foo", - "bar".to_string(), - )], - ); - let mut buf = Vec::new(); - suggestions.write_into(&mut buf).unwrap(); - let mut cursor = Cursor::new(&buf[..]); - let suggestions = Suggestions::read_from(&mut cursor).unwrap(); - assert_eq!(suggestions, suggestions); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_commands_packet.rs b/azalea-protocol/src/packets/game/clientbound_commands_packet.rs deleted file mode 100755 index 10055e37..00000000 --- a/azalea-protocol/src/packets/game/clientbound_commands_packet.rs +++ /dev/null @@ -1,380 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_core::{bitset::FixedBitSet, resource_location::ResourceLocation}; -use azalea_protocol_macros::ClientboundGamePacket; -use tracing::warn; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCommandsPacket { - pub entries: Vec, - #[var] - pub root_index: u32, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct BrigadierNodeStub { - pub is_executable: bool, - pub children: Vec, - pub redirect_node: Option, - pub node_type: NodeType, -} - -#[derive(Debug, Clone, Eq)] -pub struct BrigadierNumber { - pub min: Option, - pub max: Option, -} -impl BrigadierNumber { - pub fn new(min: Option, max: Option) -> BrigadierNumber { - BrigadierNumber { min, max } - } -} -impl PartialEq for BrigadierNumber { - fn eq(&self, other: &Self) -> bool { - match (&self.min, &self.max, &other.min, &other.max) { - (Some(f_min), None, Some(s_min), None) => f_min == s_min, - (None, Some(f_max), None, Some(s_max)) => f_max == s_max, - (Some(f_min), Some(f_max), Some(s_min), Some(s_max)) => { - f_min == s_min && f_max == s_max - } - (None, None, None, None) => true, - _ => false, - } - } -} - -impl McBufReadable for BrigadierNumber { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let flags = FixedBitSet::<2>::read_from(buf)?; - let min = if flags.index(0) { - Some(T::read_from(buf)?) - } else { - None - }; - let max = if flags.index(1) { - Some(T::read_from(buf)?) - } else { - None - }; - Ok(BrigadierNumber { min, max }) - } -} -impl McBufWritable for BrigadierNumber { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut flags = FixedBitSet::<2>::new(); - if self.min.is_some() { - flags.set(0); - } - if self.max.is_some() { - flags.set(1); - } - flags.write_into(buf)?; - if let Some(min) = &self.min { - min.write_into(buf)?; - } - if let Some(max) = &self.max { - max.write_into(buf)?; - } - Ok(()) - } -} - -#[derive(Debug, Clone, Copy, McBuf, PartialEq, Eq)] -pub enum BrigadierString { - /// Reads a single word - SingleWord = 0, - // If it starts with a ", keeps reading until another " (allowing escaping with \). Otherwise - // behaves the same as SINGLE_WORD - QuotablePhrase = 1, - // Reads the rest of the content after the cursor. Quotes will not be removed. - GreedyPhrase = 2, -} - -#[derive(Debug, Clone, McBuf, PartialEq)] -pub enum BrigadierParser { - Bool, - Float(BrigadierNumber), - Double(BrigadierNumber), - Integer(BrigadierNumber), - Long(BrigadierNumber), - String(BrigadierString), - Entity(EntityParser), - GameProfile, - BlockPos, - ColumnPos, - Vec3, - Vec2, - BlockState, - BlockPredicate, - ItemStack, - ItemPredicate, - Color, - FormattedText, - Style, - Message, - NbtCompoundTag, - NbtTag, - NbtPath, - Objective, - ObjectiveCriteria, - Operation, - Particle, - Angle, - Rotation, - ScoreboardSlot, - ScoreHolder { allows_multiple: bool }, - Swizzle, - Team, - ItemSlot, - ItemSlots, - ResourceLocation, - Function, - EntityAnchor, - IntRange, - FloatRange, - Dimension, - GameMode, - Time { min: i32 }, - ResourceOrTag { registry_key: ResourceLocation }, - ResourceOrTagKey { registry_key: ResourceLocation }, - Resource { registry_key: ResourceLocation }, - ResourceKey { registry_key: ResourceLocation }, - TemplateMirror, - TemplateRotation, - Heightmap, - LootTable, - LootPredicate, - LootModifier, - Uuid, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EntityParser { - pub single: bool, - pub players_only: bool, -} -impl McBufReadable for EntityParser { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let flags = FixedBitSet::<2>::read_from(buf)?; - Ok(EntityParser { - single: flags.index(0), - players_only: flags.index(1), - }) - } -} -impl McBufWritable for EntityParser { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut flags = FixedBitSet::<2>::new(); - if self.single { - flags.set(0); - } - if self.players_only { - flags.set(1); - } - flags.write_into(buf)?; - Ok(()) - } -} - -// TODO: BrigadierNodeStub should have more stuff -impl McBufReadable for BrigadierNodeStub { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let flags = FixedBitSet::<8>::read_from(buf)?; - if flags.index(5) || flags.index(6) || flags.index(7) { - warn!("Warning: The flags from a Brigadier node are over 31. This is probably a bug.",); - } - - let node_type = u8::from(flags.index(0)) + (u8::from(flags.index(1)) * 2); - let is_executable = flags.index(2); - let has_redirect = flags.index(3); - let has_suggestions_type = flags.index(4); - - let children = Vec::::var_read_from(buf)?; - let redirect_node = if has_redirect { - Some(u32::var_read_from(buf)?) - } else { - None - }; - - // argument node - if node_type == 2 { - let name = String::read_from(buf)?; - let parser = BrigadierParser::read_from(buf)?; - let suggestions_type = if has_suggestions_type { - Some(ResourceLocation::read_from(buf)?) - } else { - None - }; - let node = BrigadierNodeStub { - is_executable, - children, - redirect_node, - node_type: NodeType::Argument { - name, - parser, - suggestions_type, - }, - }; - return Ok(node); - } - // literal node - else if node_type == 1 { - let name = String::read_from(buf)?; - return Ok(BrigadierNodeStub { - is_executable, - children, - redirect_node, - node_type: NodeType::Literal { name }, - }); - } - Ok(BrigadierNodeStub { - is_executable, - children, - redirect_node, - node_type: NodeType::Root, - }) - } -} - -impl McBufWritable for BrigadierNodeStub { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut flags = FixedBitSet::<4>::new(); - if self.is_executable { - flags.set(2); - } - if self.redirect_node.is_some() { - flags.set(3); - } - - match &self.node_type { - NodeType::Root => { - flags.write_into(buf)?; - - self.children.var_write_into(buf)?; - - if let Some(redirect) = self.redirect_node { - redirect.var_write_into(buf)?; - } - } - NodeType::Literal { name } => { - flags.set(0); - flags.write_into(buf)?; - - self.children.var_write_into(buf)?; - - if let Some(redirect) = self.redirect_node { - redirect.var_write_into(buf)?; - } - - name.write_into(buf)?; - } - NodeType::Argument { - name, - parser, - suggestions_type, - } => { - flags.set(1); - if suggestions_type.is_some() { - flags.set(4); - } - flags.write_into(buf)?; - - self.children.var_write_into(buf)?; - - if let Some(redirect) = self.redirect_node { - redirect.var_write_into(buf)?; - } - - name.write_into(buf)?; - parser.write_into(buf)?; - - if let Some(suggestion) = suggestions_type { - suggestion.write_into(buf)?; - } - } - } - Ok(()) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub enum NodeType { - Root, - Literal { - name: String, - }, - Argument { - name: String, - parser: BrigadierParser, - suggestions_type: Option, - }, -} - -impl BrigadierNodeStub { - #[must_use] - pub fn name(&self) -> Option<&str> { - match &self.node_type { - NodeType::Root => None, - NodeType::Literal { name } | NodeType::Argument { name, .. } => Some(name), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_brigadier_node_stub_root() { - let data = BrigadierNodeStub { - is_executable: false, - children: vec![1, 2], - redirect_node: None, - node_type: NodeType::Root, - }; - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - let read_data = BrigadierNodeStub::read_from(&mut data_cursor).unwrap(); - assert_eq!(data, read_data); - } - - #[test] - fn test_brigadier_node_stub_literal() { - let data = BrigadierNodeStub { - is_executable: true, - children: vec![], - redirect_node: None, - node_type: NodeType::Literal { - name: "String".to_string(), - }, - }; - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - let read_data = BrigadierNodeStub::read_from(&mut data_cursor).unwrap(); - assert_eq!(data, read_data); - } - - #[test] - fn test_brigadier_node_stub_argument() { - let data = BrigadierNodeStub { - is_executable: false, - children: vec![6, 9], - redirect_node: Some(5), - node_type: NodeType::Argument { - name: "position".to_string(), - parser: BrigadierParser::Vec3, - suggestions_type: Some(ResourceLocation::new("minecraft:test_suggestion")), - }, - }; - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - let read_data = BrigadierNodeStub::read_from(&mut data_cursor).unwrap(); - assert_eq!(data, read_data); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_container_close_packet.rs b/azalea-protocol/src/packets/game/clientbound_container_close_packet.rs deleted file mode 100644 index a59da450..00000000 --- a/azalea-protocol/src/packets/game/clientbound_container_close_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundContainerClosePacket { - pub container_id: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs b/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs deleted file mode 100755 index 4e08232d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_container_set_content_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundContainerSetContentPacket { - pub container_id: i8, - #[var] - pub state_id: u32, - pub items: Vec, - pub carried_item: ItemSlot, -} diff --git a/azalea-protocol/src/packets/game/clientbound_container_set_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_container_set_data_packet.rs deleted file mode 100755 index dc53a024..00000000 --- a/azalea-protocol/src/packets/game/clientbound_container_set_data_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundContainerSetDataPacket { - pub container_id: i8, - pub id: u16, - pub value: u16, -} diff --git a/azalea-protocol/src/packets/game/clientbound_container_set_slot_packet.rs b/azalea-protocol/src/packets/game/clientbound_container_set_slot_packet.rs deleted file mode 100755 index 9b954fa0..00000000 --- a/azalea-protocol/src/packets/game/clientbound_container_set_slot_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundContainerSetSlotPacket { - pub container_id: i8, - #[var] - pub state_id: u32, - pub slot: u16, - pub item_stack: ItemSlot, -} diff --git a/azalea-protocol/src/packets/game/clientbound_cookie_request_packet.rs b/azalea-protocol/src/packets/game/clientbound_cookie_request_packet.rs deleted file mode 100755 index 9f1c1d43..00000000 --- a/azalea-protocol/src/packets/game/clientbound_cookie_request_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCookieRequestPacket { - pub key: ResourceLocation, -} diff --git a/azalea-protocol/src/packets/game/clientbound_cooldown_packet.rs b/azalea-protocol/src/packets/game/clientbound_cooldown_packet.rs deleted file mode 100755 index 41c8291a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_cooldown_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCooldownPacket { - pub item: azalea_registry::Item, - #[var] - pub duration: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs deleted file mode 100755 index 3165bbbe..00000000 --- a/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs +++ /dev/null @@ -1,15 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCustomChatCompletionsPacket { - pub action: Action, - pub entries: Vec, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - Add = 0, - Remove = 1, - Set = 2, -} diff --git a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs deleted file mode 100755 index fb5f11ba..00000000 --- a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_buf::UnsizedByteArray; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCustomPayloadPacket { - pub identifier: ResourceLocation, - pub data: UnsizedByteArray, -} diff --git a/azalea-protocol/src/packets/game/clientbound_custom_report_details_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_report_details_packet.rs deleted file mode 100644 index a098f915..00000000 --- a/azalea-protocol/src/packets/game/clientbound_custom_report_details_packet.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::collections::HashMap; - -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCustomReportDetailsPacket { - // azalea doesn't implement max lengths yet - - // max length = 32 - // key string is limited to 128 bytes - // value string is limited to 4096 bytes - pub details: HashMap, -} diff --git a/azalea-protocol/src/packets/game/clientbound_custom_sound_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_sound_packet.rs deleted file mode 100644 index 05b1560b..00000000 --- a/azalea-protocol/src/packets/game/clientbound_custom_sound_packet.rs +++ /dev/null @@ -1,28 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundCustomSoundPacket { - pub name: ResourceLocation, - pub source: SoundSource, - pub x: i32, - pub y: i32, - pub z: i32, - pub volume: f32, - pub pitch: f32, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum SoundSource { - Master = 0, - Music = 1, - Records = 2, - Weather = 3, - Blocks = 4, - Hostile = 5, - Neutral = 6, - Players = 7, - Ambient = 8, - Voice = 9, -} diff --git a/azalea-protocol/src/packets/game/clientbound_damage_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_damage_event_packet.rs deleted file mode 100644 index cf5d369a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_damage_event_packet.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; -use azalea_core::position::Vec3; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundDamageEventPacket { - #[var] - pub entity_id: u32, - #[var] - pub source_type_id: u32, - pub source_cause_id: OptionalEntityId, - pub source_direct_id: OptionalEntityId, - pub source_position: Option, -} - -#[derive(Clone, Debug)] -pub struct OptionalEntityId(pub Option); -impl McBufReadable for OptionalEntityId { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - match u32::var_read_from(buf)? { - 0 => Ok(OptionalEntityId(None)), - id => Ok(OptionalEntityId(Some(id - 1))), - } - } -} -impl McBufWritable for OptionalEntityId { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self.0 { - Some(id) => (id + 1).var_write_into(buf), - None => 0u32.var_write_into(buf), - } - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_debug_sample_packet.rs b/azalea-protocol/src/packets/game/clientbound_debug_sample_packet.rs deleted file mode 100755 index 641fd05e..00000000 --- a/azalea-protocol/src/packets/game/clientbound_debug_sample_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::serverbound_debug_sample_subscription::RemoteDebugSampleType; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundDebugSamplePacket { - pub sample: Vec, - pub debug_sample_type: RemoteDebugSampleType, -} diff --git a/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs deleted file mode 100755 index eef9b561..00000000 --- a/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::clientbound_player_chat_packet::PackedMessageSignature; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundDeleteChatPacket { - pub signature: PackedMessageSignature, -} diff --git a/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs b/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs deleted file mode 100755 index f8771c37..00000000 --- a/azalea-protocol/src/packets/game/clientbound_disconnect_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundDisconnectPacket { - pub reason: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs deleted file mode 100644 index 24e1a992..00000000 --- a/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs +++ /dev/null @@ -1,42 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::{ - translatable_component::{StringOrComponent, TranslatableComponent}, - FormattedText, -}; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::clientbound_player_chat_packet::ChatTypeBound; - -// A disguised chat packet is basically the same as a normal -// [`ClientboundPlayerChatPacket`], except that it doesn't have any of the chat -// signing things. Vanilla servers use this when messages are sent from the -// console. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket, PartialEq)] -pub struct ClientboundDisguisedChatPacket { - pub message: FormattedText, - pub chat_type: ChatTypeBound, -} - -impl ClientboundDisguisedChatPacket { - /// Get the full message, including the sender part. - #[must_use] - pub fn message(&self) -> FormattedText { - let sender = self.chat_type.name.clone(); - let content = self.message.clone(); - let target = self.chat_type.target_name.clone(); - - let translation_key = self.chat_type.chat_type.chat_translation_key(); - - let mut args = vec![ - StringOrComponent::FormattedText(sender), - StringOrComponent::FormattedText(content), - ]; - if let Some(target) = target { - args.push(StringOrComponent::FormattedText(target)); - } - - let component = TranslatableComponent::new(translation_key.to_string(), args); - - FormattedText::Translatable(component) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs deleted file mode 100755 index 18076a33..00000000 --- a/azalea-protocol/src/packets/game/clientbound_entity_event_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundEntityEventPacket { - pub entity_id: u32, - pub event_id: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_entity_position_sync_packet.rs b/azalea-protocol/src/packets/game/clientbound_entity_position_sync_packet.rs deleted file mode 100755 index 0125eeb4..00000000 --- a/azalea-protocol/src/packets/game/clientbound_entity_position_sync_packet.rs +++ /dev/null @@ -1,19 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::Vec3; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundEntityPositionSyncPacket { - #[var] - pub id: u32, - pub values: PositionMoveRotation, - pub on_ground: bool, -} - -#[derive(McBuf, Clone, Debug)] -pub struct PositionMoveRotation { - pub position: Vec3, - pub delta_movement: Vec3, - pub y_rot: f32, - pub x_rot: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_explode_packet.rs b/azalea-protocol/src/packets/game/clientbound_explode_packet.rs deleted file mode 100755 index 23c416d1..00000000 --- a/azalea-protocol/src/packets/game/clientbound_explode_packet.rs +++ /dev/null @@ -1,166 +0,0 @@ -use std::{ - io::{Cursor, Write}, - str::FromStr, -}; - -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_core::{position::BlockPos, resource_location::ResourceLocation}; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::{ParticleKind, SoundEvent}; - -#[derive(Clone, Debug, PartialEq, ClientboundGamePacket)] -pub struct ClientboundExplodePacket { - pub x: f64, - pub y: f64, - pub z: f64, - pub power: f32, - pub to_blow: Vec, - pub knockback_x: f32, - pub knockback_y: f32, - pub knockback_z: f32, - pub block_interaction: BlockInteraction, - pub small_explosion_particles: ParticleKind, - pub large_explosion_particles: ParticleKind, - pub explosion_sound: SoundEvent, -} - -#[derive(Clone, Copy, Debug, PartialEq, McBuf)] -pub enum BlockInteraction { - Keep, - Destroy, - DestroyWithDecay, - TriggerBlock, -} - -impl McBufReadable for ClientboundExplodePacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let x = f64::read_from(buf)?; - let y = f64::read_from(buf)?; - let z = f64::read_from(buf)?; - let power = f32::read_from(buf)?; - - let x_floor = x.floor() as i32; - let y_floor = y.floor() as i32; - let z_floor = z.floor() as i32; - - let to_blow_len = u32::var_read_from(buf)?; - let mut to_blow = Vec::with_capacity(to_blow_len as usize); - for _ in 0..to_blow_len { - // the bytes are offsets from the main x y z - let x = x_floor + i32::from(i8::read_from(buf)?); - let y = y_floor + i32::from(i8::read_from(buf)?); - let z = z_floor + i32::from(i8::read_from(buf)?); - to_blow.push(BlockPos { x, y, z }); - } - - let knockback_x = f32::read_from(buf)?; - let knockback_y = f32::read_from(buf)?; - let knockback_z = f32::read_from(buf)?; - - let block_interaction = BlockInteraction::read_from(buf)?; - let small_explosion_particles = ParticleKind::read_from(buf)?; - let large_explosion_particles = ParticleKind::read_from(buf)?; - - let sound_event_resource_location = ResourceLocation::read_from(buf)?.to_string(); - let explosion_sound = - SoundEvent::from_str(&sound_event_resource_location).map_err(|_| { - BufReadError::UnexpectedStringEnumVariant { - id: sound_event_resource_location, - } - })?; - - Ok(Self { - x, - y, - z, - power, - to_blow, - knockback_x, - knockback_y, - knockback_z, - block_interaction, - small_explosion_particles, - large_explosion_particles, - explosion_sound, - }) - } -} - -impl McBufWritable for ClientboundExplodePacket { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.x.write_into(buf)?; - self.y.write_into(buf)?; - self.z.write_into(buf)?; - self.power.write_into(buf)?; - - let to_blow_len = self.to_blow.len() as u32; - to_blow_len.var_write_into(buf)?; - - let x_floor = self.x.floor() as i32; - let y_floor = self.y.floor() as i32; - let z_floor = self.z.floor() as i32; - - for pos in &self.to_blow { - let x = (pos.x - x_floor) as i8; - let y = (pos.y - y_floor) as i8; - let z = (pos.z - z_floor) as i8; - x.write_into(buf)?; - y.write_into(buf)?; - z.write_into(buf)?; - } - - self.knockback_x.write_into(buf)?; - self.knockback_y.write_into(buf)?; - self.knockback_z.write_into(buf)?; - - self.block_interaction.write_into(buf)?; - self.small_explosion_particles.write_into(buf)?; - self.large_explosion_particles.write_into(buf)?; - - let sound_event_resource_location = - ResourceLocation::new(&self.explosion_sound.to_string()); - sound_event_resource_location.write_into(buf)?; - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_read_write() { - let packet = ClientboundExplodePacket { - x: 123_456.0, - y: 789_012.0, - z: 345_678.0, - power: 1_000.0, - to_blow: vec![ - BlockPos { - x: 123_456 + 1, - y: 789_012 + 2, - z: 345_678 - 127, - }, - BlockPos { - x: 123_456 + 4, - y: 789_012 - 5, - z: 345_678 + 6, - }, - ], - knockback_x: 1_000.0, - knockback_y: 2_000.0, - knockback_z: 3_000.0, - block_interaction: BlockInteraction::Destroy, - small_explosion_particles: ParticleKind::Explosion, - large_explosion_particles: ParticleKind::ExplosionEmitter, - explosion_sound: SoundEvent::EntityGenericExplode, - }; - let mut buf = Vec::new(); - packet.write_into(&mut buf).unwrap(); - let packet2 = ClientboundExplodePacket::read_from(&mut Cursor::new(&buf)).unwrap(); - assert_eq!(packet, packet2); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_forget_level_chunk_packet.rs b/azalea-protocol/src/packets/game/clientbound_forget_level_chunk_packet.rs deleted file mode 100755 index 027d41ee..00000000 --- a/azalea-protocol/src/packets/game/clientbound_forget_level_chunk_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::ChunkPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundForgetLevelChunkPacket { - pub pos: ChunkPos, -} diff --git a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs deleted file mode 100755 index 2416f7c3..00000000 --- a/azalea-protocol/src/packets/game/clientbound_game_event_packet.rs +++ /dev/null @@ -1,26 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundGameEventPacket { - pub event: EventType, - pub param: f32, -} - -#[derive(Clone, Debug, Copy, McBuf)] -pub enum EventType { - NoRespawnBlockAvailable = 0, - StartRaining = 1, - StopRaining = 2, - ChangeGameMode = 3, - WinGame = 4, - DemoEvent = 5, - ArrowHitPlayer = 6, - RainLevelChange = 7, - ThunderLevelChange = 8, - PufferFishSting = 9, - GuardianElderEffect = 10, - ImmediateRespawn = 11, - LimitedCrafting = 12, - WaitForLevelChunks = 13, -} diff --git a/azalea-protocol/src/packets/game/clientbound_horse_screen_open_packet.rs b/azalea-protocol/src/packets/game/clientbound_horse_screen_open_packet.rs deleted file mode 100755 index ad3f7b37..00000000 --- a/azalea-protocol/src/packets/game/clientbound_horse_screen_open_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundHorseScreenOpenPacket { - pub container_id: u8, - #[var] - pub size: u32, - pub entity_id: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_hurt_animation_packet.rs b/azalea-protocol/src/packets/game/clientbound_hurt_animation_packet.rs deleted file mode 100644 index d4a79a27..00000000 --- a/azalea-protocol/src/packets/game/clientbound_hurt_animation_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundHurtAnimationPacket { - #[var] - pub id: u32, - pub yaw: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs b/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs deleted file mode 100755 index 77742c0a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_initialize_border_packet.rs +++ /dev/null @@ -1,18 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, ClientboundGamePacket, McBuf)] -pub struct ClientboundInitializeBorderPacket { - pub new_center_x: f64, - pub new_center_z: f64, - pub old_size: f64, - pub new_size: f64, - #[var] - pub lerp_time: u64, - #[var] - pub new_absolute_max_size: u32, - #[var] - pub warning_blocks: u32, - #[var] - pub warning_time: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs b/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs deleted file mode 100755 index 16fe3357..00000000 --- a/azalea-protocol/src/packets/game/clientbound_keep_alive_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundKeepAlivePacket { - pub id: u64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs deleted file mode 100755 index f7212ba7..00000000 --- a/azalea-protocol/src/packets/game/clientbound_level_chunk_with_light_packet.rs +++ /dev/null @@ -1,66 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use simdnbt::owned::Nbt; - -use super::clientbound_light_update_packet::ClientboundLightUpdatePacketData; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundLevelChunkWithLightPacket { - pub x: i32, - pub z: i32, - pub chunk_data: ClientboundLevelChunkPacketData, - pub light_data: ClientboundLightUpdatePacketData, -} - -#[derive(Clone, Debug, McBuf)] -pub struct ClientboundLevelChunkPacketData { - pub heightmaps: Nbt, - // we can't parse the data in azalea-protocol because it depends on context from other packets - pub data: Vec, - pub block_entities: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct BlockEntity { - pub packed_xz: u8, - pub y: u16, - pub kind: azalea_registry::BlockEntityKind, - pub data: Nbt, -} - -#[cfg(test)] -mod tests { - use std::{io::Cursor, ops::Deref}; - - use azalea_buf::McBufReadable; - use azalea_world::Chunk; - use simdnbt::owned::BaseNbt; - - use super::*; - - #[test] - fn test_clientbound_level_chunk_with_light_packet() { - #[rustfmt::skip] - let bytes = [ - 255, 255, 255, 253, 0, 0, 0, 1, 10, 12, 0, 15, 77, 79, 84, 73, 79, 78, 95, 66, 76, 79, 67, 75, 73, 78, 71, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 240, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 33, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 37, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 2, 0, 137, 51, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 2, 0, 137, 51, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 140, 1, 1, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 4, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 32, 67, 101, 0, 0, 0, 0, 0, 32, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 33, 67, 101, 135, 169, 203, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 33, 67, 101, 135, 169, 203, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 16, 50, 84, 118, 152, 186, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 33, 67, 101, 135, 169, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 16, 50, 84, 118, 152, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 33, 67, 101, 135, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 16, 50, 84, 118, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 33, 67, 101, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 128, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 16, 50, 84, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 16, 50, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let packet = - ClientboundLevelChunkWithLightPacket::read_from(&mut Cursor::new(&bytes)).unwrap(); - - let heightmaps_nbt = &packet.chunk_data.heightmaps; - // necessary to make the unwrap_or work - let empty_nbt = BaseNbt::default(); - let heightmaps = heightmaps_nbt.unwrap_or(&empty_nbt).deref(); - - let chunk = Chunk::read_with_dimension_height( - &mut Cursor::new(&packet.chunk_data.data), - 256, - 0, - heightmaps, - ) - .unwrap(); - - assert_eq!(chunk.sections.len(), 16); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs deleted file mode 100755 index a79217f1..00000000 --- a/azalea-protocol/src/packets/game/clientbound_level_event_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundLevelEventPacket { - pub event_type: u32, - pub pos: BlockPos, - pub data: u32, - pub global_event: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs deleted file mode 100755 index eae99634..00000000 --- a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs +++ /dev/null @@ -1,39 +0,0 @@ -use azalea_buf::McBuf; -use azalea_entity::particle::Particle; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundLevelParticlesPacket { - pub override_limiter: bool, - pub x: f64, - pub y: f64, - pub z: f64, - pub x_dist: f32, - pub y_dist: f32, - pub z_dist: f32, - pub max_speed: f32, - pub count: u32, - pub particle: Particle, -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use azalea_buf::McBufReadable; - - use super::*; - - #[test] - fn test_clientbound_level_particles_packet() { - let slice = &[ - 0, 64, 139, 10, 0, 0, 0, 0, 0, 192, 26, 0, 0, 0, 0, 0, 0, 64, 144, 58, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 63, 128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 63, 128, 0, 0, - ][..]; - let mut bytes = Cursor::new(slice); - - let _packet = ClientboundLevelParticlesPacket::read_from(&mut bytes).unwrap(); - assert_eq!(bytes.position(), slice.len() as u64); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs deleted file mode 100755 index 8d50e94d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs +++ /dev/null @@ -1,22 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::bitset::BitSet; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundLightUpdatePacket { - #[var] - pub x: i32, - #[var] - pub z: i32, - pub light_data: ClientboundLightUpdatePacketData, -} - -#[derive(Clone, Debug, McBuf)] -pub struct ClientboundLightUpdatePacketData { - pub sky_y_mask: BitSet, - pub block_y_mask: BitSet, - pub empty_sky_y_mask: BitSet, - pub empty_block_y_mask: BitSet, - pub sky_updates: Vec>, - pub block_updates: Vec>, -} diff --git a/azalea-protocol/src/packets/game/clientbound_login_packet.rs b/azalea-protocol/src/packets/game/clientbound_login_packet.rs deleted file mode 100755 index 234439d5..00000000 --- a/azalea-protocol/src/packets/game/clientbound_login_packet.rs +++ /dev/null @@ -1,27 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -use crate::packets::common::CommonPlayerSpawnInfo; - -/// The first packet sent by the server to the client after login. -/// -/// This packet contains information about the state of the player, the -/// world, and the registry. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundLoginPacket { - pub player_id: u32, - pub hardcore: bool, - pub levels: Vec, - #[var] - pub max_players: i32, - #[var] - pub chunk_radius: u32, - #[var] - pub simulation_distance: u32, - pub reduced_debug_info: bool, - pub show_death_screen: bool, - pub do_limited_crafting: bool, - pub common: CommonPlayerSpawnInfo, - pub enforces_secure_chat: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_map_item_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_map_item_data_packet.rs deleted file mode 100755 index 0f858181..00000000 --- a/azalea-protocol/src/packets/game/clientbound_map_item_data_packet.rs +++ /dev/null @@ -1,88 +0,0 @@ -use azalea_buf::{McBuf, McBufReadable, McBufWritable}; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, ClientboundGamePacket, McBuf)] -pub struct ClientboundMapItemDataPacket { - #[var] - pub map_id: u32, - pub scale: u8, - pub locked: bool, - pub decorations: Option>, - pub color_patch: OptionalMapPatch, -} - -#[derive(Clone, Debug, McBuf)] -pub struct MapDecoration { - pub decoration_type: DecorationType, - pub x: i8, - pub y: i8, - /// Minecraft does & 15 on this value, azalea-protocol doesn't. I don't - /// think it matters. - pub rot: i8, - pub name: Option, -} - -#[derive(Debug, Clone)] -pub struct OptionalMapPatch(pub Option); - -impl McBufReadable for OptionalMapPatch { - fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result { - let pos = buf.position(); - Ok(Self(if u8::read_from(buf)? == 0 { - None - } else { - buf.set_position(pos); - Some(MapPatch::read_from(buf)?) - })) - } -} - -impl McBufWritable for OptionalMapPatch { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - match &self.0 { - None => 0u8.write_into(buf), - Some(m) => m.write_into(buf), - } - } -} - -#[derive(Debug, Clone, McBuf)] -pub struct MapPatch { - pub width: u8, - pub height: u8, - pub start_x: u8, - pub start_y: u8, - pub map_colors: Vec, -} - -#[derive(Clone, Copy, Debug, McBuf)] -pub enum DecorationType { - Player, - Frame, - RedMarker, - BlueMarker, - TargetX, - TargetPoint, - PlayerOffMap, - PlayerOffLimits, - Mansion, - Monument, - BannerWhite, - BannerOrange, - BannerMagenta, - BannerLightBlue, - BannerYellow, - BannerLime, - BannerPink, - BannerGray, - BannerLightGray, - BannerCyan, - BannerPurple, - BannerBlue, - BannerBrown, - BannerGreen, - BannerRed, - BannerBlack, - RedX, -} diff --git a/azalea-protocol/src/packets/game/clientbound_merchant_offers_packet.rs b/azalea-protocol/src/packets/game/clientbound_merchant_offers_packet.rs deleted file mode 100755 index 4253ace4..00000000 --- a/azalea-protocol/src/packets/game/clientbound_merchant_offers_packet.rs +++ /dev/null @@ -1,30 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMerchantOffersPacket { - #[var] - pub container_id: u32, - pub offers: Vec, - #[var] - pub villager_level: u32, - #[var] - pub villager_xp: u32, - pub show_progress: bool, - pub can_restock: bool, -} - -#[derive(Clone, Debug, McBuf)] -pub struct MerchantOffer { - pub base_cost_a: ItemSlot, - pub result: ItemSlot, - pub cost_b: ItemSlot, - pub out_of_stock: bool, - pub uses: u32, - pub max_uses: u32, - pub xp: u32, - pub special_price_diff: i32, - pub price_multiplier: f32, - pub demand: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs deleted file mode 100755 index d909fdcc..00000000 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::delta::PositionDelta8; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMoveEntityPosPacket { - #[var] - pub entity_id: u32, - pub delta: PositionDelta8, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_rot_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_pos_rot_packet.rs deleted file mode 100755 index 5a5dfbd3..00000000 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_pos_rot_packet.rs +++ /dev/null @@ -1,14 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::delta::PositionDelta8; -use azalea_protocol_macros::ClientboundGamePacket; - -/// This packet is sent by the server when an entity moves less then 8 blocks. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMoveEntityPosRotPacket { - #[var] - pub entity_id: u32, - pub delta: PositionDelta8, - pub y_rot: i8, - pub x_rot: i8, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs deleted file mode 100755 index 666abe23..00000000 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_rot_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMoveEntityRotPacket { - #[var] - pub entity_id: u32, - pub y_rot: i8, - pub x_rot: i8, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_move_minecart_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_minecart_packet.rs deleted file mode 100644 index 014e2aaa..00000000 --- a/azalea-protocol/src/packets/game/clientbound_move_minecart_packet.rs +++ /dev/null @@ -1,19 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::Vec3; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMoveMinecartPacket { - #[var] - pub entity_id: u32, - pub lerp_steps: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct MinecartStep { - pub position: Vec3, - pub movement: Vec3, - pub y_rot: u8, - pub x_rot: u8, - pub weight: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_move_vehicle_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_vehicle_packet.rs deleted file mode 100755 index d2376c35..00000000 --- a/azalea-protocol/src/packets/game/clientbound_move_vehicle_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundMoveVehiclePacket { - pub x: f64, - pub y: f64, - pub z: f64, - pub y_rot: f32, - pub x_rot: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_open_book_packet.rs b/azalea-protocol/src/packets/game/clientbound_open_book_packet.rs deleted file mode 100755 index 1b450b80..00000000 --- a/azalea-protocol/src/packets/game/clientbound_open_book_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::serverbound_interact_packet::InteractionHand; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundOpenBookPacket { - pub hand: InteractionHand, -} diff --git a/azalea-protocol/src/packets/game/clientbound_open_screen_packet.rs b/azalea-protocol/src/packets/game/clientbound_open_screen_packet.rs deleted file mode 100755 index 582cac17..00000000 --- a/azalea-protocol/src/packets/game/clientbound_open_screen_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundOpenScreenPacket { - #[var] - pub container_id: u32, - pub menu_type: azalea_registry::MenuKind, - pub title: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_open_sign_editor_packet.rs b/azalea-protocol/src/packets/game/clientbound_open_sign_editor_packet.rs deleted file mode 100755 index 0b03cbe2..00000000 --- a/azalea-protocol/src/packets/game/clientbound_open_sign_editor_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundOpenSignEditorPacket { - pub pos: BlockPos, - pub is_front_text: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_ping_packet.rs b/azalea-protocol/src/packets/game/clientbound_ping_packet.rs deleted file mode 100755 index 0bd2c8c3..00000000 --- a/azalea-protocol/src/packets/game/clientbound_ping_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPingPacket { - pub id: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_place_ghost_recipe_packet.rs b/azalea-protocol/src/packets/game/clientbound_place_ghost_recipe_packet.rs deleted file mode 100755 index 4d61a526..00000000 --- a/azalea-protocol/src/packets/game/clientbound_place_ghost_recipe_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlaceGhostRecipePacket { - pub container_id: u8, - pub recipe: ResourceLocation, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs deleted file mode 100755 index 48c8b41a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_abilities_packet.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBuf}; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::bitset::FixedBitSet; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerAbilitiesPacket { - pub flags: PlayerAbilitiesFlags, - pub flying_speed: f32, - /// Used for the fov - pub walking_speed: f32, -} - -#[derive(Clone, Debug)] -pub struct PlayerAbilitiesFlags { - pub invulnerable: bool, - pub flying: bool, - pub can_fly: bool, - pub instant_break: bool, -} - -impl McBufReadable for PlayerAbilitiesFlags { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<4>::read_from(buf)?; - Ok(PlayerAbilitiesFlags { - invulnerable: set.index(0), - flying: set.index(1), - can_fly: set.index(2), - instant_break: set.index(3), - }) - } -} - -impl McBufWritable for PlayerAbilitiesFlags { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<4>::new(); - if self.invulnerable { - set.set(0); - } - if self.flying { - set.set(1); - } - if self.can_fly { - set.set(2); - } - if self.instant_break { - set.set(3); - } - set.write_into(buf) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs deleted file mode 100755 index 0e86a36d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_crypto::{MessageSignature, SignedMessageHeader}; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerChatHeaderPacket { - pub header: SignedMessageHeader, - pub header_signature: MessageSignature, - pub body_digest: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs deleted file mode 100644 index 9cd20efc..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs +++ /dev/null @@ -1,202 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_chat::{ - translatable_component::{StringOrComponent, TranslatableComponent}, - FormattedText, -}; -use azalea_core::bitset::BitSet; -use azalea_crypto::MessageSignature; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket, PartialEq)] -pub struct ClientboundPlayerChatPacket { - pub sender: Uuid, - #[var] - pub index: u32, - pub signature: Option, - pub body: PackedSignedMessageBody, - pub unsigned_content: Option, - pub filter_mask: FilterMask, - pub chat_type: ChatTypeBound, -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct PackedSignedMessageBody { - // the error is here, for some reason it skipped a byte earlier and here - // it's reading `0` when it should be `11` - pub content: String, - pub timestamp: u64, - pub salt: u64, - pub last_seen: PackedLastSeenMessages, -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct PackedLastSeenMessages { - pub entries: Vec, -} - -/// Messages can be deleted by either their signature or message id. -#[derive(Clone, Debug, PartialEq)] -pub enum PackedMessageSignature { - Signature(Box), - Id(u32), -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub enum FilterMask { - PassThrough, - FullyFiltered, - PartiallyFiltered(BitSet), -} - -#[derive(Copy, Clone, Debug, McBuf, PartialEq, Eq)] -pub enum ChatType { - Chat = 0, - SayCommand = 1, - MsgCommandIncoming = 2, - MsgCommandOutgoing = 3, - TeamMsgCommandIncoming = 4, - TeamMsgCommandOutgoing = 5, - EmoteCommand = 6, -} - -#[derive(Clone, Debug, McBuf, PartialEq)] -pub struct ChatTypeBound { - pub chat_type: ChatType, - pub name: FormattedText, - pub target_name: Option, -} - -// must be in Client -#[derive(Clone, Debug, PartialEq)] -pub struct MessageSignatureCache { - pub entries: Vec>, -} - -// impl MessageSignatureCache { -// pub fn unpacker(&self) -> impl Fn(u32) -> Option { - -// } -// } - -// impl PackedSignedMessageBody { -// pub fn unpack(&self, unpacker: impl Fn(u32) -> Option) -// {} } - -impl ClientboundPlayerChatPacket { - /// Returns the content of the message. If you want to get the FormattedText - /// for the whole message including the sender part, use - /// [`ClientboundPlayerChatPacket::message`]. - #[must_use] - pub fn content(&self) -> FormattedText { - self.unsigned_content - .clone() - .unwrap_or_else(|| FormattedText::from(self.body.content.clone())) - } - - /// Get the full message, including the sender part. - #[must_use] - pub fn message(&self) -> FormattedText { - let sender = self.chat_type.name.clone(); - let content = self.content(); - let target = self.chat_type.target_name.clone(); - - let translation_key = self.chat_type.chat_type.chat_translation_key(); - - let mut args = vec![ - StringOrComponent::FormattedText(sender), - StringOrComponent::FormattedText(content), - ]; - if let Some(target) = target { - args.push(StringOrComponent::FormattedText(target)); - } - - let component = TranslatableComponent::new(translation_key.to_string(), args); - - FormattedText::Translatable(component) - } -} - -impl ChatType { - #[must_use] - pub fn chat_translation_key(&self) -> &'static str { - match self { - ChatType::Chat => "chat.type.text", - ChatType::SayCommand => "chat.type.announcement", - ChatType::MsgCommandIncoming => "commands.message.display.incoming", - ChatType::MsgCommandOutgoing => "commands.message.display.outgoing", - ChatType::TeamMsgCommandIncoming => "chat.type.team.text", - ChatType::TeamMsgCommandOutgoing => "chat.type.team.sent", - ChatType::EmoteCommand => "chat.type.emote", - } - } - - #[must_use] - pub fn narrator_translation_key(&self) -> &'static str { - match self { - ChatType::EmoteCommand => "chat.type.emote", - _ => "chat.type.text.narrate", - } - } -} - -impl McBufReadable for PackedMessageSignature { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let id = u32::var_read_from(buf)?; - if id == 0 { - let full_signature = MessageSignature::read_from(buf)?; - - Ok(PackedMessageSignature::Signature(Box::new(full_signature))) - } else { - Ok(PackedMessageSignature::Id(id - 1)) - } - } -} -impl McBufWritable for PackedMessageSignature { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - PackedMessageSignature::Signature(full_signature) => { - 0u32.var_write_into(buf)?; - full_signature.write_into(buf)?; - } - PackedMessageSignature::Id(id) => { - (id + 1).var_write_into(buf)?; - } - } - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_read_player_chat_packet() { - let mut bytes = Cursor::new( - &[ - 55, 186, 28, 76, 92, 167, 177, 75, 188, 158, 200, 179, 191, 227, 16, 171, 145, 0, - 0, 4, 116, 101, 115, 116, 0, 0, 1, 140, 178, 225, 89, 103, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, - 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 12, 75, - 97, 115, 117, 109, 105, 77, 97, 114, 105, 115, 97, 11, 0, 2, 105, 100, 0, 0, 0, 4, - 186, 28, 76, 92, 167, 177, 75, 188, 158, 200, 179, 191, 227, 16, 171, 145, 8, 0, 4, - 116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108, - 97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111, - 119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69, - 118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103, - 101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117, - 101, 0, 19, 47, 116, 101, 108, 108, 32, 75, 97, 115, 117, 109, 105, 77, 97, 114, - 105, 115, 97, 32, 0, 9, 0, 5, 101, 120, 116, 114, 97, 8, 0, 0, 0, 3, 0, 0, 0, 12, - 75, 97, 115, 117, 109, 105, 77, 97, 114, 105, 115, 97, 0, 0, 8, 0, 9, 105, 110, - 115, 101, 114, 116, 105, 111, 110, 0, 12, 75, 97, 115, 117, 109, 105, 77, 97, 114, - 105, 115, 97, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 0, - ][..], - ); - let _packet = ClientboundPlayerChatPacket::read_from(&mut bytes).unwrap(); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_combat_end_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_combat_end_packet.rs deleted file mode 100755 index dafb839f..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_combat_end_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -/// Unused by the client in vanilla. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerCombatEndPacket { - #[var] - pub duration: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_combat_enter_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_combat_enter_packet.rs deleted file mode 100755 index 42ee1838..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_combat_enter_packet.rs +++ /dev/null @@ -1,6 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -/// Unused in vanilla. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerCombatEnterPacket {} diff --git a/azalea-protocol/src/packets/game/clientbound_player_combat_kill_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_combat_kill_packet.rs deleted file mode 100755 index c309342f..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_combat_kill_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -/// Used to send a respawn screen. -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerCombatKillPacket { - #[var] - pub player_id: u32, - pub message: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_info_remove_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_info_remove_packet.rs deleted file mode 100644 index bb620272..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_info_remove_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerInfoRemovePacket { - pub profile_ids: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_info_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_info_update_packet.rs deleted file mode 100644 index 2b286e64..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_info_update_packet.rs +++ /dev/null @@ -1,313 +0,0 @@ -use std::{ - collections::HashMap, - io::{Cursor, Write}, -}; - -use azalea_auth::game_profile::{GameProfile, ProfilePropertyValue}; -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_chat::FormattedText; -use azalea_core::{bitset::FixedBitSet, game_type::GameMode}; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -use super::serverbound_chat_session_update_packet::RemoteChatSessionData; - -#[derive(Clone, Debug, ClientboundGamePacket)] -pub struct ClientboundPlayerInfoUpdatePacket { - pub actions: ActionEnumSet, - pub entries: Vec, -} - -#[derive(Clone, Debug, Default)] -pub struct PlayerInfoEntry { - pub profile: GameProfile, - pub listed: bool, - pub latency: i32, - pub game_mode: GameMode, - pub display_name: Option, - pub list_order: i32, - pub chat_session: Option, -} - -#[derive(Clone, Debug, McBuf)] -pub struct AddPlayerAction { - pub name: String, - pub properties: HashMap, -} -#[derive(Clone, Debug, McBuf)] -pub struct InitializeChatAction { - pub chat_session: Option, -} -#[derive(Clone, Debug, McBuf)] -pub struct UpdateGameModeAction { - pub game_mode: GameMode, -} -#[derive(Clone, Debug, McBuf)] -pub struct UpdateListedAction { - pub listed: bool, -} -#[derive(Clone, Debug, McBuf)] -pub struct UpdateLatencyAction { - #[var] - pub latency: i32, -} -#[derive(Clone, Debug, McBuf)] -pub struct UpdateDisplayNameAction { - pub display_name: Option, -} -#[derive(Clone, Debug, McBuf)] -pub struct UpdateListOrderAction { - #[var] - pub list_order: i32, -} - -impl McBufReadable for ClientboundPlayerInfoUpdatePacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let actions = ActionEnumSet::read_from(buf)?; - let mut entries = Vec::new(); - - let entry_count = u32::var_read_from(buf)?; - for _ in 0..entry_count { - let profile_id = Uuid::read_from(buf)?; - let mut entry = PlayerInfoEntry::default(); - entry.profile.uuid = profile_id; - - if actions.add_player { - let action = AddPlayerAction::read_from(buf)?; - entry.profile.name = action.name; - entry.profile.properties = action.properties; - } - if actions.initialize_chat { - let action = InitializeChatAction::read_from(buf)?; - entry.chat_session = action.chat_session; - } - if actions.update_game_mode { - let action = UpdateGameModeAction::read_from(buf)?; - entry.game_mode = action.game_mode; - } - if actions.update_listed { - let action = UpdateListedAction::read_from(buf)?; - entry.listed = action.listed; - } - if actions.update_latency { - let action = UpdateLatencyAction::read_from(buf)?; - entry.latency = action.latency; - } - if actions.update_display_name { - let action = UpdateDisplayNameAction::read_from(buf)?; - entry.display_name = action.display_name; - } - if actions.update_list_order { - let action = UpdateListOrderAction::read_from(buf)?; - entry.list_order = action.list_order; - } - - entries.push(entry); - } - - Ok(ClientboundPlayerInfoUpdatePacket { actions, entries }) - } -} - -impl McBufWritable for ClientboundPlayerInfoUpdatePacket { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.actions.write_into(buf)?; - - (self.entries.len() as u32).var_write_into(buf)?; - for entry in &self.entries { - entry.profile.uuid.write_into(buf)?; - - if self.actions.add_player { - AddPlayerAction { - name: entry.profile.name.clone(), - properties: entry.profile.properties.clone(), - } - .write_into(buf)?; - } - if self.actions.initialize_chat { - InitializeChatAction { - chat_session: entry.chat_session.clone(), - } - .write_into(buf)?; - } - if self.actions.update_game_mode { - UpdateGameModeAction { - game_mode: entry.game_mode, - } - .write_into(buf)?; - } - if self.actions.update_listed { - UpdateListedAction { - listed: entry.listed, - } - .write_into(buf)?; - } - if self.actions.update_latency { - UpdateLatencyAction { - latency: entry.latency, - } - .write_into(buf)?; - } - if self.actions.update_display_name { - UpdateDisplayNameAction { - display_name: entry.display_name.clone(), - } - .write_into(buf)?; - } - } - - Ok(()) - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct ActionEnumSet { - pub add_player: bool, - pub initialize_chat: bool, - pub update_game_mode: bool, - pub update_listed: bool, - pub update_latency: bool, - pub update_display_name: bool, - pub update_list_order: bool, -} - -impl McBufReadable for ActionEnumSet { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<7>::read_from(buf)?; - Ok(ActionEnumSet { - add_player: set.index(0), - initialize_chat: set.index(1), - update_game_mode: set.index(2), - update_listed: set.index(3), - update_latency: set.index(4), - update_display_name: set.index(5), - update_list_order: set.index(6), - }) - } -} - -impl McBufWritable for ActionEnumSet { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<7>::new(); - if self.add_player { - set.set(0); - } - if self.initialize_chat { - set.set(1); - } - if self.update_game_mode { - set.set(2); - } - if self.update_listed { - set.set(3); - } - if self.update_latency { - set.set(4); - } - if self.update_display_name { - set.set(5); - } - if self.update_list_order { - set.set(6); - } - set.write_into(buf)?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_action_enum_set() { - let data = ActionEnumSet { - add_player: true, - initialize_chat: false, - update_game_mode: true, - update_listed: false, - update_latency: true, - update_display_name: false, - update_list_order: true, - }; - let mut buf = Vec::new(); - data.write_into(&mut buf).unwrap(); - let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf); - let read_data = ActionEnumSet::read_from(&mut data_cursor).unwrap(); - assert_eq!(read_data, data); - } - - #[test] - fn read_player_info_update_packet() { - // from wynncraft - let mut bytes = Cursor::new( - &[ - 63, 1, 196, 217, 99, 243, 221, 101, 79, 183, 167, 88, 48, 71, 25, 49, 5, 142, 5, - 74, 66, 76, 80, 78, 1, 8, 116, 101, 120, 116, 117, 114, 101, 115, 152, 3, 101, 119, - 111, 103, 73, 67, 74, 48, 97, 87, 49, 108, 99, 51, 82, 104, 98, 88, 65, 105, 73, - 68, 111, 103, 77, 84, 99, 119, 77, 106, 99, 49, 78, 106, 89, 48, 77, 68, 81, 120, - 78, 105, 119, 75, 73, 67, 65, 105, 99, 72, 74, 118, 90, 109, 108, 115, 90, 85, 108, - 107, 73, 105, 65, 54, 73, 67, 74, 106, 78, 71, 81, 53, 78, 106, 78, 109, 77, 50, - 82, 107, 78, 106, 85, 48, 90, 109, 73, 51, 89, 84, 99, 49, 79, 68, 77, 119, 78, 68, - 99, 120, 79, 84, 77, 120, 77, 68, 85, 52, 90, 83, 73, 115, 67, 105, 65, 103, 73, - 110, 66, 121, 98, 50, 90, 112, 98, 71, 86, 79, 89, 87, 49, 108, 73, 105, 65, 54, - 73, 67, 74, 75, 81, 107, 120, 81, 84, 105, 73, 115, 67, 105, 65, 103, 73, 110, 78, - 112, 90, 50, 53, 104, 100, 72, 86, 121, 90, 86, 74, 108, 99, 88, 86, 112, 99, 109, - 86, 107, 73, 105, 65, 54, 73, 72, 82, 121, 100, 87, 85, 115, 67, 105, 65, 103, 73, - 110, 82, 108, 101, 72, 82, 49, 99, 109, 86, 122, 73, 105, 65, 54, 73, 72, 115, 75, - 73, 67, 65, 103, 73, 67, 74, 84, 83, 48, 108, 79, 73, 105, 65, 54, 73, 72, 115, 75, - 73, 67, 65, 103, 73, 67, 65, 103, 73, 110, 86, 121, 98, 67, 73, 103, 79, 105, 65, - 105, 97, 72, 82, 48, 99, 68, 111, 118, 76, 51, 82, 108, 101, 72, 82, 49, 99, 109, - 86, 122, 76, 109, 49, 112, 98, 109, 86, 106, 99, 109, 70, 109, 100, 67, 53, 117, - 90, 88, 81, 118, 100, 71, 86, 52, 100, 72, 86, 121, 90, 83, 56, 48, 79, 68, 107, - 120, 89, 84, 107, 50, 89, 84, 74, 107, 77, 84, 103, 120, 78, 84, 69, 49, 79, 68, - 107, 52, 78, 68, 89, 119, 77, 68, 82, 106, 77, 106, 100, 104, 78, 50, 86, 106, 77, - 106, 85, 53, 77, 87, 77, 120, 79, 68, 66, 108, 77, 84, 70, 109, 77, 122, 104, 107, - 89, 122, 69, 52, 77, 84, 74, 109, 77, 106, 100, 104, 77, 71, 82, 108, 78, 50, 69, - 120, 77, 87, 85, 120, 73, 103, 111, 103, 73, 67, 65, 103, 102, 81, 111, 103, 73, - 72, 48, 75, 102, 81, 61, 61, 1, 172, 5, 117, 69, 67, 88, 54, 83, 104, 55, 67, 100, - 87, 49, 77, 99, 78, 88, 122, 72, 73, 105, 90, 86, 43, 103, 111, 121, 47, 120, 53, - 102, 51, 65, 113, 119, 50, 115, 102, 114, 104, 106, 67, 118, 67, 102, 97, 54, 67, - 112, 55, 88, 116, 109, 103, 118, 113, 73, 114, 122, 100, 85, 72, 90, 102, 79, 100, - 100, 112, 109, 87, 70, 110, 70, 119, 97, 85, 109, 97, 76, 106, 86, 102, 121, 88, - 119, 115, 76, 48, 78, 108, 118, 98, 56, 78, 104, 121, 115, 113, 87, 47, 104, 75, - 120, 101, 86, 117, 90, 68, 71, 43, 102, 54, 98, 99, 98, 81, 113, 76, 79, 54, 83, - 66, 88, 111, 81, 74, 85, 104, 74, 66, 90, 102, 88, 78, 53, 51, 100, 102, 80, 98, - 75, 89, 81, 54, 68, 77, 57, 87, 102, 113, 81, 76, 100, 55, 121, 117, 119, 90, 81, - 68, 55, 120, 48, 54, 118, 102, 105, 72, 121, 48, 110, 87, 50, 99, 68, 111, 72, 101, - 71, 102, 72, 67, 53, 104, 52, 112, 84, 109, 65, 101, 100, 101, 109, 116, 48, 67, - 72, 113, 86, 54, 76, 67, 77, 89, 118, 101, 110, 84, 88, 68, 83, 81, 107, 82, 43, - 50, 53, 74, 76, 120, 101, 98, 74, 105, 98, 108, 54, 88, 106, 73, 118, 88, 120, 105, - 87, 68, 121, 85, 49, 65, 43, 121, 48, 79, 104, 53, 89, 115, 116, 121, 86, 116, 106, - 107, 76, 113, 67, 56, 85, 57, 118, 86, 110, 87, 65, 102, 111, 43, 52, 104, 78, 43, - 79, 51, 122, 108, 72, 117, 84, 50, 87, 76, 86, 121, 98, 43, 88, 72, 100, 67, 111, - 111, 88, 75, 82, 75, 83, 86, 71, 101, 122, 103, 75, 78, 47, 53, 65, 53, 67, 119, - 78, 112, 82, 87, 98, 81, 55, 109, 90, 47, 108, 51, 57, 84, 114, 100, 84, 99, 54, - 121, 79, 88, 73, 48, 56, 83, 101, 73, 54, 68, 118, 118, 50, 55, 78, 66, 112, 107, - 47, 97, 72, 119, 65, 49, 116, 105, 78, 108, 55, 122, 49, 103, 97, 79, 107, 113, - 107, 116, 54, 120, 85, 116, 70, 84, 85, 122, 72, 71, 97, 107, 69, 118, 105, 76, 72, - 120, 67, 99, 106, 98, 121, 88, 111, 76, 71, 101, 101, 50, 57, 81, 84, 73, 102, 99, - 97, 69, 56, 104, 108, 110, 73, 97, 74, 111, 115, 72, 117, 57, 116, 100, 54, 52, - 119, 74, 88, 74, 115, 69, 78, 114, 121, 69, 56, 70, 53, 52, 52, 116, 114, 84, 54, - 105, 112, 122, 73, 119, 43, 118, 120, 112, 76, 121, 88, 65, 87, 116, 103, 83, 113, - 76, 108, 107, 121, 78, 50, 77, 115, 57, 74, 89, 110, 100, 79, 111, 90, 57, 77, 53, - 84, 49, 87, 112, 75, 70, 97, 52, 55, 114, 112, 80, 106, 75, 114, 79, 107, 114, 110, - 100, 50, 97, 83, 51, 90, 86, 77, 120, 118, 79, 49, 111, 78, 47, 100, 84, 55, 116, - 77, 119, 82, 52, 109, 97, 55, 85, 73, 68, 50, 48, 84, 113, 105, 83, 75, 56, 108, - 76, 85, 100, 53, 48, 86, 119, 108, 112, 67, 116, 98, 76, 99, 71, 86, 82, 98, 78, - 84, 97, 108, 90, 83, 66, 56, 88, 65, 72, 72, 78, 100, 116, 88, 86, 50, 49, 111, 68, - 77, 116, 77, 122, 79, 104, 82, 109, 43, 57, 88, 81, 90, 79, 50, 55, 66, 69, 71, 65, - 47, 119, 117, 104, 113, 71, 108, 106, 82, 111, 76, 72, 111, 102, 98, 71, 48, 52, - 82, 55, 84, 43, 80, 99, 112, 77, 116, 65, 69, 105, 49, 100, 57, 99, 66, 90, 115, - 119, 84, 105, 107, 113, 114, 89, 49, 86, 49, 48, 106, 104, 77, 76, 118, 99, 99, 78, - 50, 109, 70, 43, 89, 86, 81, 101, 48, 90, 55, 43, 78, 100, 119, 119, 104, 121, 47, - 108, 79, 72, 81, 54, 71, 108, 122, 74, 110, 87, 122, 103, 50, 107, 61, 0, 255, 255, - 255, 255, 15, 1, 255, 255, 255, 255, 15, 1, 10, 8, 0, 4, 116, 101, 120, 116, 0, 0, - 0, - ][..], - ); - let _packet = ClientboundPlayerInfoUpdatePacket::read_from(&mut bytes).unwrap(); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_look_at_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_look_at_packet.rs deleted file mode 100755 index 47c63d1f..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_look_at_packet.rs +++ /dev/null @@ -1,24 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerLookAtPacket { - pub from_anchor: Anchor, - pub x: f64, - pub y: f64, - pub z: f64, - pub entity: Option, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Anchor { - Feet = 0, - Eyes = 1, -} - -#[derive(McBuf, Clone, Debug)] -pub struct AtEntity { - #[var] - pub entity: u32, - pub to_anchor: Anchor, -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs deleted file mode 100755 index 2a9cebc6..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; -use azalea_core::{bitset::FixedBitSet, position::Vec3}; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerPositionPacket { - #[var] - pub id: u32, - pub pos: Vec3, - pub delta_movement: Vec3, - pub y_rot: f32, - pub x_rot: f32, - pub relative_arguments: RelativeMovements, -} - -#[derive(Debug, Clone)] -pub struct RelativeMovements { - pub x: bool, - pub y: bool, - pub z: bool, - pub y_rot: bool, - pub x_rot: bool, -} - -impl McBufReadable for RelativeMovements { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - // yes minecraft seriously wastes that many bits, smh - let set = FixedBitSet::<32>::read_from(buf)?; - Ok(RelativeMovements { - x: set.index(0), - y: set.index(1), - z: set.index(2), - y_rot: set.index(3), - x_rot: set.index(4), - }) - } -} - -impl McBufWritable for RelativeMovements { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<5>::new(); - if self.x { - set.set(0); - } - if self.y { - set.set(1); - } - if self.z { - set.set(2); - } - if self.y_rot { - set.set(3); - } - if self.x_rot { - set.set(4); - } - set.write_into(buf) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_player_rotation_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_rotation_packet.rs deleted file mode 100755 index a1ad9bbe..00000000 --- a/azalea-protocol/src/packets/game/clientbound_player_rotation_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPlayerRotationPacket { - pub y_rot: f32, - pub x_rot: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_pong_response_packet.rs b/azalea-protocol/src/packets/game/clientbound_pong_response_packet.rs deleted file mode 100755 index 0b48198e..00000000 --- a/azalea-protocol/src/packets/game/clientbound_pong_response_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundPongResponsePacket { - pub time: u64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_projectile_power_packet.rs b/azalea-protocol/src/packets/game/clientbound_projectile_power_packet.rs deleted file mode 100644 index a665a2aa..00000000 --- a/azalea-protocol/src/packets/game/clientbound_projectile_power_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundProjectilePowerPacket { - pub id: u32, - pub acceleration_power: f64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_book_add_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_book_add_packet.rs deleted file mode 100755 index e025da7d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_recipe_book_add_packet.rs +++ /dev/null @@ -1,79 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::clientbound_update_recipes_packet::{Ingredient, SlotDisplayData}; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRecipeBookAddPacket { - pub entries: Vec, - pub replace: bool, -} - -#[derive(Clone, Debug, McBuf)] -pub struct Entry { - pub contents: RecipeDisplayEntry, - pub flags: u8, -} - -#[derive(Clone, Debug, McBuf)] -pub struct RecipeDisplayEntry { - #[var] - pub id: u32, - pub display: RecipeDisplayData, - // ByteBufCodecs.OPTIONAL_VAR_INT - #[var] - pub group: u32, - pub category: azalea_registry::RecipeBookCategory, - pub crafting_requirements: Option>, -} - -/// [`azalea_registry::RecipeDisplay`] -#[derive(Clone, Debug, McBuf)] -pub enum RecipeDisplayData { - Shapeless(ShapelessCraftingRecipeDisplay), - Shaped(ShapedCraftingRecipeDisplay), - Furnace(FurnaceRecipeDisplay), - Stonecutter(StonecutterRecipeDisplay), - Smithing(SmithingRecipeDisplay), -} - -#[derive(Clone, Debug, McBuf)] -pub struct ShapelessCraftingRecipeDisplay { - pub ingredients: Vec, - pub result: SlotDisplayData, - pub crafting_station: SlotDisplayData, -} -#[derive(Clone, Debug, McBuf)] -pub struct ShapedCraftingRecipeDisplay { - #[var] - pub width: u32, - #[var] - pub height: u32, - pub ingredients: Vec, - pub result: SlotDisplayData, - pub crafting_station: SlotDisplayData, -} -#[derive(Clone, Debug, McBuf)] -pub struct FurnaceRecipeDisplay { - pub ingredient: SlotDisplayData, - pub fuel: SlotDisplayData, - pub result: SlotDisplayData, - pub crafting_station: SlotDisplayData, - #[var] - pub duration: u32, - pub experience: f32, -} -#[derive(Clone, Debug, McBuf)] -pub struct StonecutterRecipeDisplay { - pub input: SlotDisplayData, - pub result: SlotDisplayData, - pub crafting_station: SlotDisplayData, -} -#[derive(Clone, Debug, McBuf)] -pub struct SmithingRecipeDisplay { - pub template: SlotDisplayData, - pub base: SlotDisplayData, - pub addition: SlotDisplayData, - pub result: SlotDisplayData, - pub crafting_station: SlotDisplayData, -} diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_book_remove_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_book_remove_packet.rs deleted file mode 100755 index 678537ca..00000000 --- a/azalea-protocol/src/packets/game/clientbound_recipe_book_remove_packet.rs +++ /dev/null @@ -1,15 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::{ - clientbound_entity_position_sync_packet::PositionMoveRotation, - clientbound_player_position_packet::RelativeMovements, -}; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRecipeBookRemovePacket { - #[var] - pub id: u32, - pub change: PositionMoveRotation, - pub relatives: RelativeMovements, -} diff --git a/azalea-protocol/src/packets/game/clientbound_recipe_book_settings_packet.rs b/azalea-protocol/src/packets/game/clientbound_recipe_book_settings_packet.rs deleted file mode 100755 index 1180bd26..00000000 --- a/azalea-protocol/src/packets/game/clientbound_recipe_book_settings_packet.rs +++ /dev/null @@ -1,22 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRecipeBookSettingsPacket { - pub book_settings: RecipeBookSettings, -} - -#[derive(Clone, Debug, McBuf)] -pub struct RecipeBookSettings { - pub gui_open: bool, - pub filtering_craftable: bool, - - pub furnace_gui_open: bool, - pub furnace_filtering_craftable: bool, - - pub blast_furnace_gui_open: bool, - pub blast_furnace_filtering_craftable: bool, - - pub smoker_gui_open: bool, - pub smoker_filtering_craftable: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs b/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs deleted file mode 100755 index 7b192333..00000000 --- a/azalea-protocol/src/packets/game/clientbound_remove_entities_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRemoveEntitiesPacket { - #[var] - pub entity_ids: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_remove_mob_effect_packet.rs b/azalea-protocol/src/packets/game/clientbound_remove_mob_effect_packet.rs deleted file mode 100755 index 87bf81bd..00000000 --- a/azalea-protocol/src/packets/game/clientbound_remove_mob_effect_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRemoveMobEffectPacket { - #[var] - pub entity_id: u32, - pub effect: azalea_registry::MobEffect, -} diff --git a/azalea-protocol/src/packets/game/clientbound_reset_score_packet.rs b/azalea-protocol/src/packets/game/clientbound_reset_score_packet.rs deleted file mode 100644 index 8b24bbdf..00000000 --- a/azalea-protocol/src/packets/game/clientbound_reset_score_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundResetScorePacket { - pub owner: String, - pub objective_name: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_resource_pack_pop_packet.rs b/azalea-protocol/src/packets/game/clientbound_resource_pack_pop_packet.rs deleted file mode 100644 index 34836c85..00000000 --- a/azalea-protocol/src/packets/game/clientbound_resource_pack_pop_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundResourcePackPopPacket { - pub id: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_resource_pack_push_packet.rs b/azalea-protocol/src/packets/game/clientbound_resource_pack_push_packet.rs deleted file mode 100644 index 1d5e00b1..00000000 --- a/azalea-protocol/src/packets/game/clientbound_resource_pack_push_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundResourcePackPushPacket { - pub id: Uuid, - pub url: String, - pub hash: String, - pub required: bool, - pub prompt: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_respawn_packet.rs b/azalea-protocol/src/packets/game/clientbound_respawn_packet.rs deleted file mode 100755 index 7e20a843..00000000 --- a/azalea-protocol/src/packets/game/clientbound_respawn_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -use crate::packets::common::CommonPlayerSpawnInfo; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRespawnPacket { - pub common: CommonPlayerSpawnInfo, - pub data_to_keep: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs b/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs deleted file mode 100755 index 2bc77540..00000000 --- a/azalea-protocol/src/packets/game/clientbound_rotate_head_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundRotateHeadPacket { - #[var] - pub entity_id: u32, - pub y_head_rot: i8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs deleted file mode 100755 index e92ca422..00000000 --- a/azalea-protocol/src/packets/game/clientbound_section_blocks_update_packet.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_block::BlockState; -use azalea_buf::{ - BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, -}; -use azalea_core::position::{ChunkSectionBlockPos, ChunkSectionPos}; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSectionBlocksUpdatePacket { - pub section_pos: ChunkSectionPos, - pub states: Vec, -} - -#[derive(Clone, Debug)] -pub struct BlockStateWithPosition { - pub pos: ChunkSectionBlockPos, - pub state: BlockState, -} - -impl McBufReadable for BlockStateWithPosition { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let data = u64::var_read_from(buf)?; - let position_part = data & 4095; - let state = (data >> 12) as u32; - let state = BlockState::try_from(state) - .map_err(|_| BufReadError::UnexpectedEnumVariant { id: state as i32 })?; - let pos = ChunkSectionBlockPos { - x: (position_part >> 8 & 15) as u8, - y: (position_part & 15) as u8, - z: (position_part >> 4 & 15) as u8, - }; - Ok(BlockStateWithPosition { pos, state }) - } -} - -impl McBufWritable for BlockStateWithPosition { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let data = (self.state.id as u64) << 12 - | (u64::from(self.pos.x) << 8 | u64::from(self.pos.z) << 4 | u64::from(self.pos.y)); - u64::var_write_into(&data, buf)?; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_select_advancements_tab_packet.rs b/azalea-protocol/src/packets/game/clientbound_select_advancements_tab_packet.rs deleted file mode 100755 index c0d5f2ee..00000000 --- a/azalea-protocol/src/packets/game/clientbound_select_advancements_tab_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSelectAdvancementsTabPacket { - pub tab: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs deleted file mode 100755 index a70a0aec..00000000 --- a/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundServerDataPacket { - pub motd: FormattedText, - pub icon_bytes: Option>, -} diff --git a/azalea-protocol/src/packets/game/clientbound_server_links_packet.rs b/azalea-protocol/src/packets/game/clientbound_server_links_packet.rs deleted file mode 100644 index 4b24a519..00000000 --- a/azalea-protocol/src/packets/game/clientbound_server_links_packet.rs +++ /dev/null @@ -1,34 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundServerLinksPacket { - pub links: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct ServerLinkEntry { - pub kind: ServerLinkKind, - pub link: String, -} - -#[derive(Clone, Debug, McBuf)] -pub enum ServerLinkKind { - Known(KnownLinkKind), - Component(FormattedText), -} - -#[derive(Clone, Copy, Debug, McBuf)] -pub enum KnownLinkKind { - BugReport, - CommunityGuidelines, - Support, - Status, - Feedback, - Community, - Website, - Forums, - News, - Announcements, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_action_bar_text_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_action_bar_text_packet.rs deleted file mode 100755 index 60b80fe9..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_action_bar_text_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetActionBarTextPacket { - pub text: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_border_center_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_border_center_packet.rs deleted file mode 100755 index d210b0ce..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_border_center_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetBorderCenterPacket { - pub new_center_x: f64, - pub new_center_z: f64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_border_lerp_size_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_border_lerp_size_packet.rs deleted file mode 100755 index 5c80e897..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_border_lerp_size_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetBorderLerpSizePacket { - pub old_size: f64, - pub new_size: f64, - #[var] - pub lerp_time: u64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_border_size_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_border_size_packet.rs deleted file mode 100755 index 3a86a720..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_border_size_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetBorderSizePacket { - pub size: f64, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_border_warning_delay_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_border_warning_delay_packet.rs deleted file mode 100755 index 4bf794ac..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_border_warning_delay_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetBorderWarningDelayPacket { - #[var] - pub warning_delay: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_border_warning_distance_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_border_warning_distance_packet.rs deleted file mode 100755 index ef1b6e17..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_border_warning_distance_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetBorderWarningDistancePacket { - #[var] - pub warning_blocks: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_camera_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_camera_packet.rs deleted file mode 100755 index 9da75dc7..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_camera_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetCameraPacket { - #[var] - pub camera_id: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center_packet.rs deleted file mode 100755 index e9aecba9..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_center_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetChunkCacheCenterPacket { - #[var] - pub x: i32, - #[var] - pub z: i32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_radius_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_radius_packet.rs deleted file mode 100755 index 9718ca56..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_chunk_cache_radius_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetChunkCacheRadiusPacket { - #[var] - pub radius: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_cursor_item_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_cursor_item_packet.rs deleted file mode 100644 index 6a67b71c..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_cursor_item_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetCursorItemPacket { - pub contents: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs deleted file mode 100755 index b45b645d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_default_spawn_position_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetDefaultSpawnPositionPacket { - pub pos: BlockPos, - pub angle: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_display_chat_preview_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_display_chat_preview_packet.rs deleted file mode 100755 index 5aee614e..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_display_chat_preview_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetDisplayChatPreviewPacket { - pub enabled: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_display_objective_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_display_objective_packet.rs deleted file mode 100755 index 7e5ed317..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_display_objective_packet.rs +++ /dev/null @@ -1,31 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetDisplayObjectivePacket { - pub slot: DisplaySlot, - pub objective_name: String, -} - -#[derive(Clone, Debug, Copy, McBuf)] -pub enum DisplaySlot { - List = 0, - Sidebar, - BelowName, - TeamBlack, - TeamDarkBlue, - TeamDarkGreen, - TeamDarkAqua, - TeamDarkRed, - TeamDarkPurple, - TeamGold, - TeamGray, - TeamDarkGray, - TeamBlue, - TeamGreen, - TeamAqua, - TeamRed, - TeamLightPurple, - TeamYellow, - TeamWhite, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs deleted file mode 100755 index 7d869650..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_entity::EntityMetadataItems; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetEntityDataPacket { - #[var] - pub id: u32, - pub packed_items: EntityMetadataItems, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs deleted file mode 100755 index ac9dd944..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_link_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetEntityLinkPacket { - pub source_id: u32, - pub dest_id: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_motion_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_motion_packet.rs deleted file mode 100755 index 4dcd807d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_entity_motion_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetEntityMotionPacket { - #[var] - pub id: u32, - pub xa: i16, - pub ya: i16, - pub za: i16, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs deleted file mode 100755 index 165d05db..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::io::Cursor; - -use azalea_buf::{BufReadError, McBuf}; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetEquipmentPacket { - #[var] - pub entity_id: u32, - pub slots: EquipmentSlots, -} - -#[derive(Clone, Debug)] -pub struct EquipmentSlots { - pub slots: Vec<(EquipmentSlot, ItemSlot)>, -} - -impl McBufReadable for EquipmentSlots { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let mut slots = vec![]; - - loop { - let equipment_byte = u8::read_from(buf)?; - let equipment_slot = - EquipmentSlot::from_byte(equipment_byte & 127).ok_or_else(|| { - BufReadError::UnexpectedEnumVariant { - id: equipment_byte.into(), - } - })?; - let item = ItemSlot::read_from(buf)?; - slots.push((equipment_slot, item)); - if equipment_byte & 128 == 0 { - break; - }; - } - - Ok(EquipmentSlots { slots }) - } -} -impl McBufWritable for EquipmentSlots { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - for i in 0..self.slots.len() { - let (equipment_slot, item) = &self.slots[i]; - let mut equipment_byte = *equipment_slot as u8; - if i != self.slots.len() - 1 { - equipment_byte |= 128; - } - equipment_byte.write_into(buf)?; - item.write_into(buf)?; - } - - Ok(()) - } -} - -#[derive(Clone, Debug, Copy, McBuf)] -pub enum EquipmentSlot { - MainHand = 0, - OffHand = 1, - Feet = 2, - Legs = 3, - Chest = 4, - Head = 5, -} - -impl EquipmentSlot { - #[must_use] - pub fn from_byte(byte: u8) -> Option { - match byte { - 0 => Some(EquipmentSlot::MainHand), - 1 => Some(EquipmentSlot::OffHand), - 2 => Some(EquipmentSlot::Feet), - 3 => Some(EquipmentSlot::Legs), - 4 => Some(EquipmentSlot::Chest), - 5 => Some(EquipmentSlot::Head), - _ => None, - } - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs deleted file mode 100755 index f9590e26..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_experience_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetExperiencePacket { - pub experience_progress: f32, - #[var] - pub experience_level: u32, - #[var] - pub total_experience: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs deleted file mode 100755 index 72b7554d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_health_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetHealthPacket { - pub health: f32, - #[var] - pub food: u32, - pub saturation: f32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_held_slot_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_held_slot_packet.rs deleted file mode 100644 index a83ae3cb..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_held_slot_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetHeldSlotPacket { - pub slot: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_objective_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_objective_packet.rs deleted file mode 100755 index a9481ad1..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_objective_packet.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{McBuf, McBufReadable, McBufWritable}; -use azalea_chat::{numbers::NumberFormat, FormattedText}; -use azalea_core::objectives::ObjectiveCriteria; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetObjectivePacket { - pub objective_name: String, - pub method: Method, -} - -#[derive(Clone, Copy, Debug, McBuf)] -pub enum MethodKind { - Add, - Remove, - Change, -} - -#[derive(Clone, Debug)] -pub enum Method { - Add { - display_name: FormattedText, - render_type: ObjectiveCriteria, - number_format: NumberFormat, - }, - Remove, - Change { - display_name: FormattedText, - render_type: ObjectiveCriteria, - number_format: NumberFormat, - }, -} - -impl McBufReadable for Method { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let kind = MethodKind::read_from(buf)?; - match kind { - MethodKind::Add => Ok(Method::Add { - display_name: FormattedText::read_from(buf)?, - render_type: ObjectiveCriteria::read_from(buf)?, - number_format: NumberFormat::read_from(buf)?, - }), - MethodKind::Remove => Ok(Method::Remove), - MethodKind::Change => Ok(Method::Change { - display_name: FormattedText::read_from(buf)?, - render_type: ObjectiveCriteria::read_from(buf)?, - number_format: NumberFormat::read_from(buf)?, - }), - } - } -} - -impl McBufWritable for Method { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - Method::Add { - display_name, - render_type, - number_format, - } => { - MethodKind::Add.write_into(buf)?; - display_name.write_into(buf)?; - render_type.write_into(buf)?; - number_format.write_into(buf)?; - } - Method::Remove => MethodKind::Remove.write_into(buf)?, - Method::Change { - display_name, - render_type, - number_format, - } => { - MethodKind::Change.write_into(buf)?; - display_name.write_into(buf)?; - render_type.write_into(buf)?; - number_format.write_into(buf)?; - } - } - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_passengers_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_passengers_packet.rs deleted file mode 100755 index ac337d6e..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_passengers_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetPassengersPacket { - #[var] - pub vehicle: u32, - #[var] - pub passengers: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_player_inventory_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_player_inventory_packet.rs deleted file mode 100644 index c17fd310..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_player_inventory_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetPlayerInventoryPacket { - #[var] - pub slot: i32, - pub contents: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_player_team_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_player_team_packet.rs deleted file mode 100755 index 724b86aa..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_player_team_packet.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; -use azalea_chat::{style::ChatFormatting, FormattedText}; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetPlayerTeamPacket { - pub name: String, - pub method: Method, -} - -#[derive(Clone, Debug)] -pub enum Method { - Add((Parameters, PlayerList)), - Remove, - Change(Parameters), - Join(PlayerList), - Leave(PlayerList), -} - -impl McBufReadable for Method { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(match u8::read_from(buf)? { - 0 => Method::Add((Parameters::read_from(buf)?, PlayerList::read_from(buf)?)), - 1 => Method::Remove, - 2 => Method::Change(Parameters::read_from(buf)?), - 3 => Method::Join(PlayerList::read_from(buf)?), - 4 => Method::Leave(PlayerList::read_from(buf)?), - id => return Err(BufReadError::UnexpectedEnumVariant { id: i32::from(id) }), - }) - } -} - -impl McBufWritable for Method { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - Method::Add((parameters, playerlist)) => { - 0u8.write_into(buf)?; - parameters.write_into(buf)?; - playerlist.write_into(buf)?; - } - Method::Remove => { - 1u8.write_into(buf)?; - } - Method::Change(parameters) => { - 2u8.write_into(buf)?; - parameters.write_into(buf)?; - } - Method::Join(playerlist) => { - 3u8.write_into(buf)?; - playerlist.write_into(buf)?; - } - Method::Leave(playerlist) => { - 4u8.write_into(buf)?; - playerlist.write_into(buf)?; - } - } - Ok(()) - } -} - -#[derive(McBuf, Clone, Debug)] -pub struct Parameters { - pub display_name: FormattedText, - pub options: u8, - pub nametag_visibility: String, - pub collision_rule: String, - pub color: ChatFormatting, - pub player_prefix: FormattedText, - pub player_suffix: FormattedText, -} - -type PlayerList = Vec; diff --git a/azalea-protocol/src/packets/game/clientbound_set_score_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_score_packet.rs deleted file mode 100755 index 6de53f74..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_score_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::{numbers::NumberFormat, FormattedText}; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetScorePacket { - pub owner: String, - pub objective_name: String, - #[var] - pub score: u32, - pub display: Option, - pub number_format: Option, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_simulation_distance_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_simulation_distance_packet.rs deleted file mode 100755 index 3efd1fa6..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_simulation_distance_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetSimulationDistancePacket { - #[var] - pub simulation_distance: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_subtitle_text_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_subtitle_text_packet.rs deleted file mode 100755 index 9b25ac05..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_subtitle_text_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetSubtitleTextPacket { - pub text: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs deleted file mode 100755 index b73f082d..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_time_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetTimePacket { - pub game_time: u64, - pub day_time: u64, - pub tick_day_time: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_title_text_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_title_text_packet.rs deleted file mode 100755 index fb00a4e5..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_title_text_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetTitleTextPacket { - pub text: FormattedText, -} diff --git a/azalea-protocol/src/packets/game/clientbound_set_titles_animation_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_titles_animation_packet.rs deleted file mode 100755 index 06faeb3c..00000000 --- a/azalea-protocol/src/packets/game/clientbound_set_titles_animation_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSetTitlesAnimationPacket { - pub fade_in: u32, - pub stay: u32, - pub fade_out: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_sound_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_sound_entity_packet.rs deleted file mode 100755 index 2e9252ae..00000000 --- a/azalea-protocol/src/packets/game/clientbound_sound_entity_packet.rs +++ /dev/null @@ -1,27 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSoundEntityPacket { - pub source: SoundSource, - #[var] - pub id: u32, - pub volume: f32, - pub pitch: f32, - #[var] - pub seed: u64, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum SoundSource { - Master = 0, - Music = 1, - Records = 2, - Weather = 3, - Blocks = 4, - Hostile = 5, - Neutral = 6, - Players = 7, - Ambient = 8, - Voice = 9, -} diff --git a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs b/azalea-protocol/src/packets/game/clientbound_sound_packet.rs deleted file mode 100755 index 4d2493ed..00000000 --- a/azalea-protocol/src/packets/game/clientbound_sound_packet.rs +++ /dev/null @@ -1,29 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::SoundEvent; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundSoundPacket { - pub sound: SoundEvent, - pub source: SoundSource, - pub x: i32, - pub y: i32, - pub z: i32, - pub volume: f32, - pub pitch: f32, - pub seed: u64, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum SoundSource { - Master = 0, - Music = 1, - Records = 2, - Weather = 3, - Blocks = 4, - Hostile = 5, - Neutral = 6, - Players = 7, - Ambient = 8, - Voice = 9, -} diff --git a/azalea-protocol/src/packets/game/clientbound_start_configuration_packet.rs b/azalea-protocol/src/packets/game/clientbound_start_configuration_packet.rs deleted file mode 100644 index b6ad9615..00000000 --- a/azalea-protocol/src/packets/game/clientbound_start_configuration_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundStartConfigurationPacket {} diff --git a/azalea-protocol/src/packets/game/clientbound_stop_sound_packet.rs b/azalea-protocol/src/packets/game/clientbound_stop_sound_packet.rs deleted file mode 100755 index 48c80237..00000000 --- a/azalea-protocol/src/packets/game/clientbound_stop_sound_packet.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; -use azalea_core::{bitset::FixedBitSet, resource_location::ResourceLocation}; -use azalea_protocol_macros::ClientboundGamePacket; - -use super::clientbound_sound_packet::SoundSource; - -#[derive(Clone, Debug, ClientboundGamePacket)] -pub struct ClientboundStopSoundPacket { - pub source: Option, - pub name: Option, -} - -impl McBufReadable for ClientboundStopSoundPacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<2>::read_from(buf)?; - let source = if set.index(0) { - Some(SoundSource::read_from(buf)?) - } else { - None - }; - let name = if set.index(1) { - Some(ResourceLocation::read_from(buf)?) - } else { - None - }; - - Ok(Self { source, name }) - } -} - -impl McBufWritable for ClientboundStopSoundPacket { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<2>::new(); - if self.source.is_some() { - set.set(0); - } - if self.name.is_some() { - set.set(1); - } - set.write_into(buf)?; - if let Some(source) = &self.source { - source.write_into(buf)?; - } - if let Some(name) = &self.name { - name.write_into(buf)?; - } - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_store_cookie_packet.rs b/azalea-protocol/src/packets/game/clientbound_store_cookie_packet.rs deleted file mode 100644 index 1c8ada28..00000000 --- a/azalea-protocol/src/packets/game/clientbound_store_cookie_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundStoreCookiePacket { - pub key: ResourceLocation, - pub payload: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs deleted file mode 100755 index 691a62a1..00000000 --- a/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs +++ /dev/null @@ -1,45 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket, PartialEq)] -pub struct ClientboundSystemChatPacket { - pub content: FormattedText, - pub overlay: bool, -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use azalea_buf::McBufReadable; - - use super::*; - - #[test] - fn test_clientbound_system_chat_packet() { - #[rustfmt::skip] - let bytes = [ - 10, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 2, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 3, 112, 121, 53, 11, 0, 2, 105, 100, 0, 0, 0, 4, 101, 54, 191, 237, 134, 149, 72, 253, 131, 161, 236, 210, 76, 242, 160, 253, 8, 0, 4, 116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108, 97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111, 119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69, 118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103, 101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117, 101, 0, 10, 47, 116, 101, 108, 108, 32, 112, 121, 53, 32, 0, 8, 0, 9, 105, 110, 115, 101, 114, 116, 105, 111, 110, 0, 3, 112, 121, 53, 8, 0, 4, 116, 101, 120, 116, 0, 3, 112, 121, 53, 0, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 1, 0, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 2, 105, 100, 0, 25, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 100, 105, 97, 109, 111, 110, 100, 95, 112, 105, 99, 107, 97, 120, 101, 8, 0, 3, 116, 97, 103, 0, 10, 123, 68, 97, 109, 97, 103, 101, 58, 48, 125, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 9, 115, 104, 111, 119, 95, 105, 116, 101, 109, 0, 9, 0, 4, 119, 105, 116, 104, 10, 0, 0, 0, 1, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 1, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 30, 105, 116, 101, 109, 46, 109, 105, 110, 101, 99, 114, 97, 102, 116, 46, 100, 105, 97, 109, 111, 110, 100, 95, 112, 105, 99, 107, 97, 120, 101, 0, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 119, 104, 105, 116, 101, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 20, 99, 104, 97, 116, 46, 115, 113, 117, 97, 114, 101, 95, 98, 114, 97, 99, 107, 101, 116, 115, 0, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0, 8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 3, 112, 121, 53, 11, 0, 2, 105, 100, 0, 0, 0, 4, 101, 54, 191, 237, 134, 149, 72, 253, 131, 161, 236, 210, 76, 242, 160, 253, 8, 0, 4, 116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108, 97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111, 119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69, 118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103, 101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117, 101, 0, 10, 47, 116, 101, 108, 108, 32, 112, 121, 53, 32, 0, 8, 0, 9, 105, 110, 115, 101, 114, 116, 105, 111, 110, 0, 3, 112, 121, 53, 8, 0, 4, 116, 101, 120, 116, 0, 3, 112, 121, 53, 0, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 28, 99, 111, 109, 109, 97, 110, 100, 115, 46, 103, 105, 118, 101, 46, 115, 117, 99, 99, 101, 115, 115, 46, 115, 105, 110, 103, 108, 101, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 114, 97, 121, 1, 0, 6, 105, 116, 97, 108, 105, 99, 1, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 15, 99, 104, 97, 116, 46, 116, 121, 112, 101, 46, 97, 100, 109, 105, 110, 0, 0 - ]; - - let packet = ClientboundSystemChatPacket::read_from(&mut Cursor::new(&bytes)).unwrap(); - assert_eq!( - packet.content.to_string(), - "[py5: Gave 1 [Diamond Pickaxe] to py5]".to_string() - ); - } - - #[test] - fn test_translate_with_string_array_clientbound_system_chat_packet() { - #[rustfmt::skip] - let bytes = [ - 10, 9, 0, 4, 119, 105, 116, 104, 8, 0, 0, 0, 1, 0, 14, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 100, 117, 115, 116, 8, 0, 9, 116, 114, 97, 110, 115, 108, 97, 116, 101, 0, 25, 99, 111, 109, 109, 97, 110, 100, 115, 46, 112, 97, 114, 116, 105, 99, 108, 101, 46, 115, 117, 99, 99, 101, 115, 115, 0, 0 - ]; - let packet = ClientboundSystemChatPacket::read_from(&mut Cursor::new(&bytes)).unwrap(); - assert_eq!( - packet.content.to_string(), - "Displaying particle minecraft:dust".to_string() - ); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_tab_list_packet.rs b/azalea-protocol/src/packets/game/clientbound_tab_list_packet.rs deleted file mode 100755 index 03557f5a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_tab_list_packet.rs +++ /dev/null @@ -1,28 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTabListPacket { - pub header: FormattedText, - pub footer: FormattedText, -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use azalea_buf::McBufReadable; - - use super::*; - - #[test] - fn test_packet_from_viaversion() { - #[rustfmt::skip] - let mut bytes = Cursor::new(&[ - 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 3, 1, 0, 4, 98, 111, 108, 100, 1, 8, 0, 4, 116, 101, 120, 116, 0, 16, 50, 66, 85, 73, 76, 68, 69, 82, 83, 50, 84, 79, 79, 76, 83, 10, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 114, 97, 121, 0, 8, 0, 0, 0, 1, 10, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 27, 80, 101, 110, 100, 105, 110, 103, 32, 99, 111, 110, 110, 101, 99, 116, 105, 111, 110, 32, 116, 111, 32, 50, 98, 50, 116, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0, 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 1, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 72, 84, 104, 105, 115, 32, 97, 99, 99, 111, 117, 110, 116, 32, 104, 97, 115, 32, 112, 114, 105, 111, 114, 105, 116, 121, 32, 115, 116, 97, 116, 117, 115, 32, 97, 110, 100, 32, 119, 105, 108, 108, 32, 98, 101, 32, 112, 108, 97, 99, 101, 100, 32, 105, 110, 32, 97, 32, 115, 104, 111, 114, 116, 101, 114, 32, 113, 117, 101, 117, 101, 46, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0 - ][..]); - let _packet = ClientboundTabListPacket::read_from(&mut bytes).unwrap(); - assert!(bytes.get_ref()[bytes.position() as usize..].is_empty()); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_tag_query_packet.rs b/azalea-protocol/src/packets/game/clientbound_tag_query_packet.rs deleted file mode 100755 index d1073cd5..00000000 --- a/azalea-protocol/src/packets/game/clientbound_tag_query_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use simdnbt::owned::NbtTag; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTagQueryPacket { - #[var] - pub transaction_id: u32, - pub tag: NbtTag, -} diff --git a/azalea-protocol/src/packets/game/clientbound_take_item_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_take_item_entity_packet.rs deleted file mode 100755 index 9e29a0fe..00000000 --- a/azalea-protocol/src/packets/game/clientbound_take_item_entity_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTakeItemEntityPacket { - #[var] - pub item_id: u32, - #[var] - pub player_id: u32, - #[var] - pub amount: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs deleted file mode 100755 index c8fbc718..00000000 --- a/azalea-protocol/src/packets/game/clientbound_teleport_entity_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::Vec3; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTeleportEntityPacket { - #[var] - pub id: u32, - pub position: Vec3, - pub y_rot: i8, - pub x_rot: i8, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_ticking_state_packet.rs b/azalea-protocol/src/packets/game/clientbound_ticking_state_packet.rs deleted file mode 100644 index a85429a2..00000000 --- a/azalea-protocol/src/packets/game/clientbound_ticking_state_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTickingStatePacket { - pub tick_rate: f32, - pub is_frozen: bool, -} diff --git a/azalea-protocol/src/packets/game/clientbound_ticking_step_packet.rs b/azalea-protocol/src/packets/game/clientbound_ticking_step_packet.rs deleted file mode 100644 index 5a5e6440..00000000 --- a/azalea-protocol/src/packets/game/clientbound_ticking_step_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTickingStepPacket { - #[var] - pub tick_steps: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_transfer_packet.rs b/azalea-protocol/src/packets/game/clientbound_transfer_packet.rs deleted file mode 100644 index dbce36e0..00000000 --- a/azalea-protocol/src/packets/game/clientbound_transfer_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundTransferPacket { - pub host: String, - #[var] - pub port: u32, -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs deleted file mode 100755 index 5934b443..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_advancements_packet.rs +++ /dev/null @@ -1,205 +0,0 @@ -use std::collections::HashMap; -use std::io::Cursor; - -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_core::resource_location::ResourceLocation; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateAdvancementsPacket { - pub reset: bool, - pub added: Vec, - pub removed: Vec, - pub progress: HashMap, -} - -#[derive(Clone, Debug, McBuf)] -pub struct Advancement { - pub parent_id: Option, - pub display: Option, - pub requirements: Vec>, - pub sends_telemetry_event: bool, -} - -#[derive(Clone, Debug)] -pub struct DisplayInfo { - pub title: FormattedText, - pub description: FormattedText, - pub icon: ItemSlot, - pub frame: FrameType, - pub show_toast: bool, - pub hidden: bool, - pub background: Option, - pub x: f32, - pub y: f32, -} - -impl azalea_buf::McBufWritable for DisplayInfo { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - self.title.write_into(buf)?; - self.description.write_into(buf)?; - self.icon.write_into(buf)?; - self.frame.write_into(buf)?; - - let mut data: u32 = 0; - if self.background.is_some() { - data |= 0b001; - } - if self.show_toast { - data |= 0b010; - } - if self.hidden { - data |= 0b100; - } - data.write_into(buf)?; - - if let Some(background) = &self.background { - background.write_into(buf)?; - } - self.x.write_into(buf)?; - self.y.write_into(buf)?; - Ok(()) - } -} -impl azalea_buf::McBufReadable for DisplayInfo { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let title = azalea_buf::McBufReadable::read_from(buf)?; - let description = azalea_buf::McBufReadable::read_from(buf)?; - let icon = azalea_buf::McBufReadable::read_from(buf)?; - let frame = azalea_buf::McBufReadable::read_from(buf)?; - - let data = u32::read_from(buf)?; - let has_background = (data & 0b1) != 0; - let show_toast = (data & 0b10) != 0; - let hidden = (data & 0b100) != 0; - - let background = if has_background { - Some(ResourceLocation::read_from(buf)?) - } else { - None - }; - let x = azalea_buf::McBufReadable::read_from(buf)?; - let y = azalea_buf::McBufReadable::read_from(buf)?; - Ok(DisplayInfo { - title, - description, - icon, - frame, - show_toast, - hidden, - background, - x, - y, - }) - } -} - -#[derive(Clone, Debug, Copy, McBuf)] -pub enum FrameType { - Task = 0, - Challenge = 1, - Goal = 2, -} - -pub type AdvancementProgress = HashMap; - -#[derive(Clone, Debug, McBuf)] -pub struct CriterionProgress { - pub date: Option, -} - -#[derive(Clone, Debug, McBuf)] -pub struct AdvancementHolder { - pub id: ResourceLocation, - pub value: Advancement, -} - -#[cfg(test)] -mod tests { - use azalea_buf::{McBufReadable, McBufWritable}; - - use super::*; - - #[test] - fn test() { - let packet = ClientboundUpdateAdvancementsPacket { - reset: true, - added: [AdvancementHolder { - id: ResourceLocation::new("minecraft:test"), - value: Advancement { - parent_id: None, - display: Some(DisplayInfo { - title: FormattedText::from("title".to_string()), - description: FormattedText::from("description".to_string()), - icon: ItemSlot::Empty, - frame: FrameType::Task, - show_toast: true, - hidden: false, - background: None, - x: 0.0, - y: 0.0, - }), - requirements: Vec::new(), - sends_telemetry_event: false, - }, - }] - .into_iter() - .collect(), - removed: vec![ResourceLocation::new("minecraft:test2")], - progress: [( - ResourceLocation::new("minecraft:test3"), - [( - "minecraft:test4".to_string(), - CriterionProgress { - date: Some(123456789), - }, - )] - .into_iter() - .collect(), - )] - .into_iter() - .collect(), - }; - - let mut data = Vec::new(); - packet.write_into(&mut data).unwrap(); - let mut buf: Cursor<&[u8]> = Cursor::new(&data); - - let read_packet = ClientboundUpdateAdvancementsPacket::read_from(&mut buf).unwrap(); - assert_eq!(packet.reset, read_packet.reset); - assert_eq!(packet.removed, read_packet.removed); - - let advancement = packet - .added - .into_iter() - .find_map(|a| { - if a.id == ResourceLocation::new("minecraft:test") { - Some(a.value) - } else { - None - } - }) - .unwrap() - .clone(); - let read_advancement = read_packet - .added - .into_iter() - .find_map(|a| { - if a.id == ResourceLocation::new("minecraft:test") { - Some(a.value) - } else { - None - } - }) - .unwrap() - .clone(); - assert_eq!(advancement.parent_id, read_advancement.parent_id); - - let display = advancement.display.unwrap(); - let read_display = read_advancement.display.unwrap(); - assert_eq!(display.title, read_display.title); - assert_eq!(display.description, read_display.description); - } -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs deleted file mode 100755 index 19d4a715..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs +++ /dev/null @@ -1,18 +0,0 @@ -use azalea_buf::McBuf; -use azalea_entity::attributes::AttributeModifier; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::Attribute; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateAttributesPacket { - #[var] - pub entity_id: u32, - pub values: Vec, -} - -#[derive(Clone, Debug, McBuf)] -pub struct AttributeSnapshot { - pub attribute: Attribute, - pub base: f64, - pub modifiers: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_enabled_features_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_enabled_features_packet.rs deleted file mode 100644 index e08358f7..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_enabled_features_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateEnabledFeaturesPacket { - pub features: Vec, -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_mob_effect_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_mob_effect_packet.rs deleted file mode 100755 index 5c7abf3a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_mob_effect_packet.rs +++ /dev/null @@ -1,15 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::MobEffect; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateMobEffectPacket { - #[var] - pub entity_id: u32, - pub mob_effect: MobEffect, - #[var] - pub effect_amplifier: u32, - #[var] - pub effect_duration_ticks: u32, - pub flags: u8, -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs deleted file mode 100755 index 4c950f90..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::collections::HashMap; - -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ClientboundGamePacket; -use azalea_registry::HolderSet; - -#[derive(Clone, Debug, PartialEq, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateRecipesPacket { - pub item_sets: HashMap, - pub stonecutter_recipes: Vec, -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct SingleInputEntry { - pub input: Ingredient, - pub recipe: SelectableRecipe, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct SelectableRecipe { - pub option_display: SlotDisplayData, -} - -/// [`azalea_registry::SlotDisplay`] -#[derive(Clone, Debug, PartialEq, McBuf)] -pub enum SlotDisplayData { - Empty, - AnyFuel, - Item(ItemSlotDisplay), - ItemStack(ItemStackSlotDisplay), - Tag(ResourceLocation), - SmithingTrim(Box), - WithRemainder(Box), - Composite(CompositeSlotDisplay), -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct ItemSlotDisplay { - pub item: azalea_registry::Item, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct ItemStackSlotDisplay { - pub stack: ItemSlot, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct TagSlotDisplay { - pub tag: azalea_registry::Item, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct SmithingTrimDemoSlotDisplay { - pub base: SlotDisplayData, - pub material: SlotDisplayData, - pub pattern: SlotDisplayData, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct WithRemainderSlotDisplay { - pub input: SlotDisplayData, - pub remainder: SlotDisplayData, -} -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct CompositeSlotDisplay { - pub contents: Vec, -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct RecipePropertySet { - pub items: Vec, -} - -#[derive(Clone, Debug, PartialEq, McBuf)] -pub struct Ingredient { - pub allowed: HolderSet, -} diff --git a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs deleted file mode 100755 index bcdef64a..00000000 --- a/azalea-protocol/src/packets/game/clientbound_update_tags_packet.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::io::Cursor; -use std::ops::Deref; -use std::{collections::HashMap, io::Write}; - -use azalea_buf::{BufReadError, McBuf, McBufVarReadable, McBufVarWritable}; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundGamePacket; - -#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] -pub struct ClientboundUpdateTagsPacket { - pub tags: TagMap, -} - -#[derive(Clone, Debug)] -pub struct Tags { - pub name: ResourceLocation, - pub elements: Vec, -} - -#[derive(Clone, Debug)] -pub struct TagMap(pub HashMap>); - -impl McBufReadable for TagMap { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let length = u32::var_read_from(buf)? as usize; - let mut data = HashMap::with_capacity(length); - for _ in 0..length { - let tag_type = ResourceLocation::read_from(buf)?; - let tags_count = i32::var_read_from(buf)? as usize; - let mut tags_vec = Vec::with_capacity(tags_count); - for _ in 0..tags_count { - let tags = Tags::read_from(buf)?; - tags_vec.push(tags); - } - data.insert(tag_type, tags_vec); - } - Ok(TagMap(data)) - } -} - -impl McBufWritable for TagMap { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (self.len() as u32).var_write_into(buf)?; - for (k, v) in &self.0 { - k.write_into(buf)?; - v.write_into(buf)?; - } - Ok(()) - } -} -impl McBufReadable for Tags { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let name = ResourceLocation::read_from(buf)?; - let elements = Vec::::var_read_from(buf)?; - Ok(Tags { name, elements }) - } -} - -impl McBufWritable for Tags { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.name.write_into(buf)?; - self.elements.var_write_into(buf)?; - Ok(()) - } -} - -impl Deref for TagMap { - type Target = HashMap>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index 55d6faaf..757dd27f 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -1,394 +1,202 @@ -pub mod clientbound_add_entity_packet; -pub mod clientbound_add_experience_orb_packet; -pub mod clientbound_animate_packet; -pub mod clientbound_award_stats_packet; -pub mod clientbound_block_changed_ack_packet; -pub mod clientbound_block_destruction_packet; -pub mod clientbound_block_entity_data_packet; -pub mod clientbound_block_event_packet; -pub mod clientbound_block_update_packet; -pub mod clientbound_boss_event_packet; -pub mod clientbound_bundle_packet; -pub mod clientbound_change_difficulty_packet; -pub mod clientbound_chunk_batch_finished_packet; -pub mod clientbound_chunk_batch_start_packet; -pub mod clientbound_chunks_biomes_packet; -pub mod clientbound_clear_titles_packet; -pub mod clientbound_command_suggestions_packet; -pub mod clientbound_commands_packet; -pub mod clientbound_container_close_packet; -pub mod clientbound_container_set_content_packet; -pub mod clientbound_container_set_data_packet; -pub mod clientbound_container_set_slot_packet; -pub mod clientbound_cookie_request_packet; -pub mod clientbound_cooldown_packet; -pub mod clientbound_custom_chat_completions_packet; -pub mod clientbound_custom_payload_packet; -pub mod clientbound_custom_report_details_packet; -pub mod clientbound_damage_event_packet; -pub mod clientbound_debug_sample_packet; -pub mod clientbound_delete_chat_packet; -pub mod clientbound_disconnect_packet; -pub mod clientbound_disguised_chat_packet; -pub mod clientbound_entity_event_packet; -pub mod clientbound_entity_position_sync_packet; -pub mod clientbound_explode_packet; -pub mod clientbound_forget_level_chunk_packet; -pub mod clientbound_game_event_packet; -pub mod clientbound_horse_screen_open_packet; -pub mod clientbound_hurt_animation_packet; -pub mod clientbound_initialize_border_packet; -pub mod clientbound_keep_alive_packet; -pub mod clientbound_level_chunk_with_light_packet; -pub mod clientbound_level_event_packet; -pub mod clientbound_level_particles_packet; -pub mod clientbound_light_update_packet; -pub mod clientbound_login_packet; -pub mod clientbound_map_item_data_packet; -pub mod clientbound_merchant_offers_packet; -pub mod clientbound_move_entity_pos_packet; -pub mod clientbound_move_entity_pos_rot_packet; -pub mod clientbound_move_entity_rot_packet; -pub mod clientbound_move_minecart_packet; -pub mod clientbound_move_vehicle_packet; -pub mod clientbound_open_book_packet; -pub mod clientbound_open_screen_packet; -pub mod clientbound_open_sign_editor_packet; -pub mod clientbound_ping_packet; -pub mod clientbound_place_ghost_recipe_packet; -pub mod clientbound_player_abilities_packet; -pub mod clientbound_player_chat_packet; -pub mod clientbound_player_combat_end_packet; -pub mod clientbound_player_combat_enter_packet; -pub mod clientbound_player_combat_kill_packet; -pub mod clientbound_player_info_remove_packet; -pub mod clientbound_player_info_update_packet; -pub mod clientbound_player_look_at_packet; -pub mod clientbound_player_position_packet; -pub mod clientbound_player_rotation_packet; -pub mod clientbound_pong_response_packet; -pub mod clientbound_projectile_power_packet; -pub mod clientbound_recipe_book_add_packet; -pub mod clientbound_recipe_book_remove_packet; -pub mod clientbound_recipe_book_settings_packet; -pub mod clientbound_remove_entities_packet; -pub mod clientbound_remove_mob_effect_packet; -pub mod clientbound_reset_score_packet; -pub mod clientbound_resource_pack_pop_packet; -pub mod clientbound_resource_pack_push_packet; -pub mod clientbound_respawn_packet; -pub mod clientbound_rotate_head_packet; -pub mod clientbound_section_blocks_update_packet; -pub mod clientbound_select_advancements_tab_packet; -pub mod clientbound_server_data_packet; -pub mod clientbound_server_links_packet; -pub mod clientbound_set_action_bar_text_packet; -pub mod clientbound_set_border_center_packet; -pub mod clientbound_set_border_lerp_size_packet; -pub mod clientbound_set_border_size_packet; -pub mod clientbound_set_border_warning_delay_packet; -pub mod clientbound_set_border_warning_distance_packet; -pub mod clientbound_set_camera_packet; -pub mod clientbound_set_chunk_cache_center_packet; -pub mod clientbound_set_chunk_cache_radius_packet; -pub mod clientbound_set_cursor_item_packet; -pub mod clientbound_set_default_spawn_position_packet; -pub mod clientbound_set_display_objective_packet; -pub mod clientbound_set_entity_data_packet; -pub mod clientbound_set_entity_link_packet; -pub mod clientbound_set_entity_motion_packet; -pub mod clientbound_set_equipment_packet; -pub mod clientbound_set_experience_packet; -pub mod clientbound_set_health_packet; -pub mod clientbound_set_held_slot_packet; -pub mod clientbound_set_objective_packet; -pub mod clientbound_set_passengers_packet; -pub mod clientbound_set_player_inventory_packet; -pub mod clientbound_set_player_team_packet; -pub mod clientbound_set_score_packet; -pub mod clientbound_set_simulation_distance_packet; -pub mod clientbound_set_subtitle_text_packet; -pub mod clientbound_set_time_packet; -pub mod clientbound_set_title_text_packet; -pub mod clientbound_set_titles_animation_packet; -pub mod clientbound_sound_entity_packet; -pub mod clientbound_sound_packet; -pub mod clientbound_start_configuration_packet; -pub mod clientbound_stop_sound_packet; -pub mod clientbound_store_cookie_packet; -pub mod clientbound_system_chat_packet; -pub mod clientbound_tab_list_packet; -pub mod clientbound_tag_query_packet; -pub mod clientbound_take_item_entity_packet; -pub mod clientbound_teleport_entity_packet; -pub mod clientbound_ticking_state_packet; -pub mod clientbound_ticking_step_packet; -pub mod clientbound_transfer_packet; -pub mod clientbound_update_advancements_packet; -pub mod clientbound_update_attributes_packet; -pub mod clientbound_update_mob_effect_packet; -pub mod clientbound_update_recipes_packet; -pub mod clientbound_update_tags_packet; -pub mod serverbound_accept_teleportation_packet; -pub mod serverbound_block_entity_tag_query_packet; -pub mod serverbound_change_difficulty_packet; -pub mod serverbound_chat_ack_packet; -pub mod serverbound_chat_command_packet; -pub mod serverbound_chat_command_signed_packet; -pub mod serverbound_chat_packet; -pub mod serverbound_chat_session_update_packet; -pub mod serverbound_chunk_batch_received_packet; -pub mod serverbound_client_command_packet; -pub mod serverbound_client_information_packet; -pub mod serverbound_client_tick_end_packet; -pub mod serverbound_command_suggestion_packet; -pub mod serverbound_configuration_acknowledged_packet; -pub mod serverbound_container_button_click_packet; -pub mod serverbound_container_click_packet; -pub mod serverbound_container_close_packet; -pub mod serverbound_container_slot_state_changed_packet; -pub mod serverbound_cookie_response_packet; -pub mod serverbound_custom_payload_packet; -pub mod serverbound_debug_sample_subscription; -pub mod serverbound_edit_book_packet; -pub mod serverbound_entity_tag_query_packet; -pub mod serverbound_interact_packet; -pub mod serverbound_jigsaw_generate_packet; -pub mod serverbound_keep_alive_packet; -pub mod serverbound_lock_difficulty_packet; -pub mod serverbound_move_player_pos_packet; -pub mod serverbound_move_player_pos_rot_packet; -pub mod serverbound_move_player_rot_packet; -pub mod serverbound_move_player_status_only_packet; -pub mod serverbound_move_vehicle_packet; -pub mod serverbound_paddle_boat_packet; -pub mod serverbound_pick_item_packet; -pub mod serverbound_ping_request_packet; -pub mod serverbound_place_recipe_packet; -pub mod serverbound_player_abilities_packet; -pub mod serverbound_player_action_packet; -pub mod serverbound_player_command_packet; -pub mod serverbound_player_input_packet; -pub mod serverbound_pong_packet; -pub mod serverbound_recipe_book_change_settings_packet; -pub mod serverbound_recipe_book_seen_recipe_packet; -pub mod serverbound_rename_item_packet; -pub mod serverbound_resource_pack_packet; -pub mod serverbound_seen_advancements_packet; -pub mod serverbound_select_bundle_item_packet; -pub mod serverbound_select_trade_packet; -pub mod serverbound_set_beacon_packet; -pub mod serverbound_set_carried_item_packet; -pub mod serverbound_set_command_block_packet; -pub mod serverbound_set_command_minecart_packet; -pub mod serverbound_set_creative_mode_slot_packet; -pub mod serverbound_set_jigsaw_block_packet; -pub mod serverbound_set_structure_block_packet; -pub mod serverbound_sign_update_packet; -pub mod serverbound_swing_packet; -pub mod serverbound_teleport_to_entity_packet; -pub mod serverbound_use_item_on_packet; -pub mod serverbound_use_item_packet; +// NOTE: This file is generated automatically by codegen/packet.py. +// Don't edit it directly! use azalea_protocol_macros::declare_state_packets; -// see GameProtocols.java in the decompiled vanilla source - -declare_state_packets!( - GamePacket, - Serverbound => { - 0x00: serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, - 0x01: serverbound_block_entity_tag_query_packet::ServerboundBlockEntityTagQueryPacket, - 0x02: serverbound_select_bundle_item_packet::ServerboundSelectBundleItemPacket, - 0x03: serverbound_change_difficulty_packet::ServerboundChangeDifficultyPacket, - 0x04: serverbound_chat_ack_packet::ServerboundChatAckPacket, - 0x05: serverbound_chat_command_packet::ServerboundChatCommandPacket, - 0x06: serverbound_chat_command_signed_packet::ServerboundChatCommandSignedPacket, - 0x07: serverbound_chat_packet::ServerboundChatPacket, - 0x08: serverbound_chat_session_update_packet::ServerboundChatSessionUpdatePacket, - 0x09: serverbound_chunk_batch_received_packet::ServerboundChunkBatchReceivedPacket, - 0x0a: serverbound_client_command_packet::ServerboundClientCommandPacket, - 0x0b: serverbound_client_tick_end_packet::ServerboundTickEndPacket, - 0x0c: serverbound_client_information_packet::ServerboundClientInformationPacket, - 0x0d: serverbound_command_suggestion_packet::ServerboundCommandSuggestionPacket, - 0x0e: serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket, - 0x0f: serverbound_container_button_click_packet::ServerboundContainerButtonClickPacket, - 0x10: serverbound_container_click_packet::ServerboundContainerClickPacket, - 0x11: serverbound_container_close_packet::ServerboundContainerClosePacket, - 0x12: serverbound_container_slot_state_changed_packet::ServerboundContainerSlotStateChangedPacket, - 0x13: serverbound_cookie_response_packet::ServerboundCookieResponsePacket, - 0x14: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, - 0x15: serverbound_debug_sample_subscription::ServerboundDebugSampleSubscription, - 0x16: serverbound_edit_book_packet::ServerboundEditBookPacket, - 0x17: serverbound_entity_tag_query_packet::ServerboundEntityTagQueryPacket, - 0x18: serverbound_interact_packet::ServerboundInteractPacket, - 0x19: serverbound_jigsaw_generate_packet::ServerboundJigsawGeneratePacket, - 0x1a: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, - 0x1b: serverbound_lock_difficulty_packet::ServerboundLockDifficultyPacket, - 0x1c: serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket, - 0x1d: serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, - 0x1e: serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket, - 0x1f: serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket, - 0x20: serverbound_move_vehicle_packet::ServerboundMoveVehiclePacket, - 0x21: serverbound_paddle_boat_packet::ServerboundPaddleBoatPacket, - 0x22: serverbound_pick_item_packet::ServerboundPickItemPacket, - 0x23: serverbound_ping_request_packet::ServerboundPingRequestPacket, - 0x24: serverbound_place_recipe_packet::ServerboundPlaceRecipePacket, - 0x25: serverbound_player_abilities_packet::ServerboundPlayerAbilitiesPacket, - 0x26: serverbound_player_action_packet::ServerboundPlayerActionPacket, - 0x27: serverbound_player_command_packet::ServerboundPlayerCommandPacket, - 0x28: serverbound_player_input_packet::ServerboundPlayerInputPacket, - 0x29: serverbound_pong_packet::ServerboundPongPacket, - 0x2a: serverbound_recipe_book_change_settings_packet::ServerboundRecipeBookChangeSettingsPacket, - 0x2b: serverbound_recipe_book_seen_recipe_packet::ServerboundRecipeBookSeenRecipePacket, - 0x2c: serverbound_rename_item_packet::ServerboundRenameItemPacket, - 0x2d: serverbound_resource_pack_packet::ServerboundResourcePackPacket, - 0x2e: serverbound_seen_advancements_packet::ServerboundSeenAdvancementsPacket, - 0x2f: serverbound_select_trade_packet::ServerboundSelectTradePacket, - 0x30: serverbound_set_beacon_packet::ServerboundSetBeaconPacket, - 0x31: serverbound_set_carried_item_packet::ServerboundSetCarriedItemPacket, - 0x32: serverbound_set_command_block_packet::ServerboundSetCommandBlockPacket, - 0x33: serverbound_set_command_minecart_packet::ServerboundSetCommandMinecartPacket, - 0x34: serverbound_set_creative_mode_slot_packet::ServerboundSetCreativeModeSlotPacket, - 0x35: serverbound_set_jigsaw_block_packet::ServerboundSetJigsawBlockPacket, - 0x36: serverbound_set_structure_block_packet::ServerboundSetStructureBlockPacket, - 0x37: serverbound_sign_update_packet::ServerboundSignUpdatePacket, - 0x38: serverbound_swing_packet::ServerboundSwingPacket, - 0x39: serverbound_teleport_to_entity_packet::ServerboundTeleportToEntityPacket, - 0x3a: serverbound_use_item_on_packet::ServerboundUseItemOnPacket, - 0x3b: serverbound_use_item_packet::ServerboundUseItemPacket, - }, - Clientbound => { - 0x00: clientbound_bundle_packet::ClientboundBundlePacket, - 0x01: clientbound_add_entity_packet::ClientboundAddEntityPacket, - 0x02: clientbound_add_experience_orb_packet::ClientboundAddExperienceOrbPacket, - 0x03: clientbound_animate_packet::ClientboundAnimatePacket, - 0x04: clientbound_award_stats_packet::ClientboundAwardStatsPacket, - 0x05: clientbound_block_changed_ack_packet::ClientboundBlockChangedAckPacket, - 0x06: clientbound_block_destruction_packet::ClientboundBlockDestructionPacket, - 0x07: clientbound_block_entity_data_packet::ClientboundBlockEntityDataPacket, - 0x08: clientbound_block_event_packet::ClientboundBlockEventPacket, - 0x09: clientbound_block_update_packet::ClientboundBlockUpdatePacket, - 0x0a: clientbound_boss_event_packet::ClientboundBossEventPacket, - 0x0b: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, - 0x0c: clientbound_chunk_batch_finished_packet::ClientboundChunkBatchFinishedPacket, - 0x0d: clientbound_chunk_batch_start_packet::ClientboundChunkBatchStartPacket, - 0x0e: clientbound_chunks_biomes_packet::ClientboundChunksBiomesPacket, - 0x0f: clientbound_clear_titles_packet::ClientboundClearTitlesPacket, - 0x10: clientbound_command_suggestions_packet::ClientboundCommandSuggestionsPacket, - 0x11: clientbound_commands_packet::ClientboundCommandsPacket, - 0x12: clientbound_container_close_packet::ClientboundContainerClosePacket, - 0x13: clientbound_container_set_content_packet::ClientboundContainerSetContentPacket, - 0x14: clientbound_container_set_data_packet::ClientboundContainerSetDataPacket, - 0x15: clientbound_container_set_slot_packet::ClientboundContainerSetSlotPacket, - 0x16: clientbound_cookie_request_packet::ClientboundCookieRequestPacket, - 0x17: clientbound_cooldown_packet::ClientboundCooldownPacket, - 0x18: clientbound_custom_chat_completions_packet::ClientboundCustomChatCompletionsPacket, - 0x19: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, - 0x1a: clientbound_damage_event_packet::ClientboundDamageEventPacket, - 0x1b: clientbound_debug_sample_packet::ClientboundDebugSamplePacket, - 0x1c: clientbound_delete_chat_packet::ClientboundDeleteChatPacket, - 0x1d: clientbound_disconnect_packet::ClientboundDisconnectPacket, - 0x1e: clientbound_disguised_chat_packet::ClientboundDisguisedChatPacket, - 0x1f: clientbound_entity_event_packet::ClientboundEntityEventPacket, - 0x20: clientbound_entity_position_sync_packet::ClientboundEntityPositionSyncPacket, - 0x21: clientbound_explode_packet::ClientboundExplodePacket, - 0x22: clientbound_forget_level_chunk_packet::ClientboundForgetLevelChunkPacket, - 0x23: clientbound_game_event_packet::ClientboundGameEventPacket, - 0x24: clientbound_horse_screen_open_packet::ClientboundHorseScreenOpenPacket, - 0x25: clientbound_hurt_animation_packet::ClientboundHurtAnimationPacket, - 0x26: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket, - 0x27: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, - 0x28: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, - 0x29: clientbound_level_event_packet::ClientboundLevelEventPacket, - 0x2a: clientbound_level_particles_packet::ClientboundLevelParticlesPacket, - 0x2b: clientbound_light_update_packet::ClientboundLightUpdatePacket, - 0x2c: clientbound_login_packet::ClientboundLoginPacket, - 0x2d: clientbound_map_item_data_packet::ClientboundMapItemDataPacket, - 0x2e: clientbound_merchant_offers_packet::ClientboundMerchantOffersPacket, - 0x2f: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket, - 0x30: clientbound_move_entity_pos_rot_packet::ClientboundMoveEntityPosRotPacket, - 0x31: clientbound_move_minecart_packet::ClientboundMoveMinecartPacket, - 0x32: clientbound_move_entity_rot_packet::ClientboundMoveEntityRotPacket, - 0x33: clientbound_move_vehicle_packet::ClientboundMoveVehiclePacket, - 0x34: clientbound_open_book_packet::ClientboundOpenBookPacket, - 0x35: clientbound_open_screen_packet::ClientboundOpenScreenPacket, - 0x36: clientbound_open_sign_editor_packet::ClientboundOpenSignEditorPacket, - 0x37: clientbound_ping_packet::ClientboundPingPacket, - 0x38: clientbound_pong_response_packet::ClientboundPongResponsePacket, - 0x39: clientbound_place_ghost_recipe_packet::ClientboundPlaceGhostRecipePacket, - 0x3a: clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket, - 0x3b: clientbound_player_chat_packet::ClientboundPlayerChatPacket, - 0x3c: clientbound_player_combat_end_packet::ClientboundPlayerCombatEndPacket, - 0x3d: clientbound_player_combat_enter_packet::ClientboundPlayerCombatEnterPacket, - 0x3e: clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, - 0x3f: clientbound_player_info_remove_packet::ClientboundPlayerInfoRemovePacket, - 0x40: clientbound_player_info_update_packet::ClientboundPlayerInfoUpdatePacket, - 0x41: clientbound_player_look_at_packet::ClientboundPlayerLookAtPacket, - 0x42: clientbound_player_position_packet::ClientboundPlayerPositionPacket, - 0x43: clientbound_player_rotation_packet::ClientboundPlayerRotationPacket, - 0x44: clientbound_recipe_book_add_packet::ClientboundRecipeBookAddPacket, - 0x45: clientbound_recipe_book_remove_packet::ClientboundRecipeBookRemovePacket, - 0x46: clientbound_recipe_book_settings_packet::ClientboundRecipeBookSettingsPacket, - 0x47: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket, - 0x48: clientbound_remove_mob_effect_packet::ClientboundRemoveMobEffectPacket, - 0x49: clientbound_reset_score_packet::ClientboundResetScorePacket, - 0x4a: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket, - 0x4b: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket, - 0x4c: clientbound_respawn_packet::ClientboundRespawnPacket, - 0x4d: clientbound_rotate_head_packet::ClientboundRotateHeadPacket, - 0x4e: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket, - 0x4f: clientbound_select_advancements_tab_packet::ClientboundSelectAdvancementsTabPacket, - 0x50: clientbound_server_data_packet::ClientboundServerDataPacket, - 0x51: clientbound_set_action_bar_text_packet::ClientboundSetActionBarTextPacket, - 0x52: clientbound_set_border_center_packet::ClientboundSetBorderCenterPacket, - 0x53: clientbound_set_border_lerp_size_packet::ClientboundSetBorderLerpSizePacket, - 0x54: clientbound_set_border_size_packet::ClientboundSetBorderSizePacket, - 0x55: clientbound_set_border_warning_delay_packet::ClientboundSetBorderWarningDelayPacket, - 0x56: clientbound_set_border_warning_distance_packet::ClientboundSetBorderWarningDistancePacket, - 0x57: clientbound_set_camera_packet::ClientboundSetCameraPacket, - 0x58: clientbound_set_chunk_cache_center_packet::ClientboundSetChunkCacheCenterPacket, - 0x59: clientbound_set_chunk_cache_radius_packet::ClientboundSetChunkCacheRadiusPacket, - 0x5a: clientbound_set_cursor_item_packet::ClientboundSetCursorItemPacket, - 0x5b: clientbound_set_default_spawn_position_packet::ClientboundSetDefaultSpawnPositionPacket, - 0x5c: clientbound_set_display_objective_packet::ClientboundSetDisplayObjectivePacket, - 0x5d: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket, - 0x5e: clientbound_set_entity_link_packet::ClientboundSetEntityLinkPacket, - 0x5f: clientbound_set_entity_motion_packet::ClientboundSetEntityMotionPacket, - 0x60: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket, - 0x61: clientbound_set_experience_packet::ClientboundSetExperiencePacket, - 0x62: clientbound_set_health_packet::ClientboundSetHealthPacket, - 0x63: clientbound_set_held_slot_packet::ClientboundSetHeldSlotPacket, - 0x64: clientbound_set_objective_packet::ClientboundSetObjectivePacket, - 0x65: clientbound_set_passengers_packet::ClientboundSetPassengersPacket, - 0x66: clientbound_set_player_inventory_packet::ClientboundSetPlayerInventoryPacket, - 0x67: clientbound_set_player_team_packet::ClientboundSetPlayerTeamPacket, - 0x68: clientbound_set_score_packet::ClientboundSetScorePacket, - 0x69: clientbound_set_simulation_distance_packet::ClientboundSetSimulationDistancePacket, - 0x6a: clientbound_set_subtitle_text_packet::ClientboundSetSubtitleTextPacket, - 0x6b: clientbound_set_time_packet::ClientboundSetTimePacket, - 0x6c: clientbound_set_title_text_packet::ClientboundSetTitleTextPacket, - 0x6d: clientbound_set_titles_animation_packet::ClientboundSetTitlesAnimationPacket, - 0x6e: clientbound_sound_entity_packet::ClientboundSoundEntityPacket, - 0x6f: clientbound_sound_packet::ClientboundSoundPacket, - 0x70: clientbound_start_configuration_packet::ClientboundStartConfigurationPacket, - 0x71: clientbound_stop_sound_packet::ClientboundStopSoundPacket, - 0x72: clientbound_store_cookie_packet::ClientboundStoreCookiePacket, - 0x73: clientbound_system_chat_packet::ClientboundSystemChatPacket, - 0x74: clientbound_tab_list_packet::ClientboundTabListPacket, - 0x75: clientbound_tag_query_packet::ClientboundTagQueryPacket, - 0x76: clientbound_take_item_entity_packet::ClientboundTakeItemEntityPacket, - 0x77: clientbound_teleport_entity_packet::ClientboundTeleportEntityPacket, - 0x78: clientbound_ticking_state_packet::ClientboundTickingStatePacket, - 0x79: clientbound_ticking_step_packet::ClientboundTickingStepPacket, - 0x7a: clientbound_transfer_packet::ClientboundTransferPacket, - 0x7b: clientbound_update_advancements_packet::ClientboundUpdateAdvancementsPacket, - 0x7c: clientbound_update_attributes_packet::ClientboundUpdateAttributesPacket, - 0x7d: clientbound_update_mob_effect_packet::ClientboundUpdateMobEffectPacket, - 0x7e: clientbound_update_recipes_packet::ClientboundUpdateRecipesPacket, - 0x7f: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, - 0x80: clientbound_projectile_power_packet::ClientboundProjectilePowerPacket, - 0x81: clientbound_custom_report_details_packet::ClientboundCustomReportDetailsPacket, - 0x82: clientbound_server_links_packet::ClientboundServerLinksPacket - } +declare_state_packets!(GamePacket, + Clientbound => [ + bundle_delimiter, + add_entity, + add_experience_orb, + animate, + award_stats, + block_changed_ack, + block_destruction, + block_entity_data, + block_event, + block_update, + boss_event, + change_difficulty, + chunk_batch_finished, + chunk_batch_start, + chunks_biomes, + clear_titles, + command_suggestions, + commands, + container_close, + container_set_content, + container_set_data, + container_set_slot, + cookie_request, + cooldown, + custom_chat_completions, + custom_payload, + damage_event, + debug_sample, + delete_chat, + disconnect, + disguised_chat, + entity_event, + entity_position_sync, + explode, + forget_level_chunk, + game_event, + horse_screen_open, + hurt_animation, + initialize_border, + keep_alive, + level_chunk_with_light, + level_event, + level_particles, + light_update, + login, + map_item_data, + merchant_offers, + move_entity_pos, + move_entity_pos_rot, + move_minecart_along_track, + move_entity_rot, + move_vehicle, + open_book, + open_screen, + open_sign_editor, + ping, + pong_response, + place_ghost_recipe, + player_abilities, + player_chat, + player_combat_end, + player_combat_enter, + player_combat_kill, + player_info_remove, + player_info_update, + player_look_at, + player_position, + player_rotation, + recipe_book_add, + recipe_book_remove, + recipe_book_settings, + remove_entities, + remove_mob_effect, + reset_score, + resource_pack_pop, + resource_pack_push, + respawn, + rotate_head, + section_blocks_update, + select_advancements_tab, + server_data, + set_action_bar_text, + set_border_center, + set_border_lerp_size, + set_border_size, + set_border_warning_delay, + set_border_warning_distance, + set_camera, + set_chunk_cache_center, + set_chunk_cache_radius, + set_cursor_item, + set_default_spawn_position, + set_display_objective, + set_entity_data, + set_entity_link, + set_entity_motion, + set_equipment, + set_experience, + set_health, + set_held_slot, + set_objective, + set_passengers, + set_player_inventory, + set_player_team, + set_score, + set_simulation_distance, + set_subtitle_text, + set_time, + set_title_text, + set_titles_animation, + sound_entity, + sound, + start_configuration, + stop_sound, + store_cookie, + system_chat, + tab_list, + tag_query, + take_item_entity, + teleport_entity, + ticking_state, + ticking_step, + transfer, + update_advancements, + update_attributes, + update_mob_effect, + update_recipes, + update_tags, + projectile_power, + custom_report_details, + server_links, + ], + Serverbound => [ + accept_teleportation, + block_entity_tag_query, + bundle_item_selected, + change_difficulty, + chat_ack, + chat_command, + chat_command_signed, + chat, + chat_session_update, + chunk_batch_received, + client_command, + client_tick_end, + client_information, + command_suggestion, + configuration_acknowledged, + container_button_click, + container_click, + container_close, + container_slot_state_changed, + cookie_response, + custom_payload, + debug_sample_subscription, + edit_book, + entity_tag_query, + interact, + jigsaw_generate, + keep_alive, + lock_difficulty, + move_player_pos, + move_player_pos_rot, + move_player_rot, + move_player_status_only, + move_vehicle, + paddle_boat, + pick_item, + ping_request, + place_recipe, + player_abilities, + player_action, + player_command, + player_input, + pong, + recipe_book_change_settings, + recipe_book_seen_recipe, + rename_item, + resource_pack, + seen_advancements, + select_trade, + set_beacon, + set_carried_item, + set_command_block, + set_command_minecart, + set_creative_mode_slot, + set_jigsaw_block, + set_structure_block, + sign_update, + swing, + teleport_to_entity, + use_item_on, + use_item, + ] ); diff --git a/azalea-protocol/src/packets/game/s_accept_teleportation.rs b/azalea-protocol/src/packets/game/s_accept_teleportation.rs new file mode 100755 index 00000000..dedc125a --- /dev/null +++ b/azalea-protocol/src/packets/game/s_accept_teleportation.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundAcceptTeleportation { + #[var] + pub id: u32, +} diff --git a/azalea-protocol/src/packets/game/s_block_entity_tag_query.rs b/azalea-protocol/src/packets/game/s_block_entity_tag_query.rs new file mode 100644 index 00000000..159f12dc --- /dev/null +++ b/azalea-protocol/src/packets/game/s_block_entity_tag_query.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundBlockEntityTagQuery { + #[var] + pub transaction_id: u32, + pub pos: BlockPos, +} diff --git a/azalea-protocol/src/packets/game/s_bundle_item_selected.rs b/azalea-protocol/src/packets/game/s_bundle_item_selected.rs new file mode 100644 index 00000000..552e51f8 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_bundle_item_selected.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundBundleItemSelected { + #[var] + pub slot_id: i32, + #[var] + pub selected_item_index: u32, +} diff --git a/azalea-protocol/src/packets/game/s_change_difficulty.rs b/azalea-protocol/src/packets/game/s_change_difficulty.rs new file mode 100755 index 00000000..7dcd3c83 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_change_difficulty.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::difficulty::Difficulty; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChangeDifficulty { + pub difficulty: Difficulty, +} diff --git a/azalea-protocol/src/packets/game/s_chat.rs b/azalea-protocol/src/packets/game/s_chat.rs new file mode 100755 index 00000000..03bafd11 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat.rs @@ -0,0 +1,20 @@ +use azalea_buf::AzBuf; +use azalea_core::bitset::FixedBitSet; +use azalea_crypto::MessageSignature; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChat { + pub message: String, + pub timestamp: u64, + pub salt: u64, + pub signature: Option, + pub last_seen_messages: LastSeenMessagesUpdate, +} + +#[derive(Clone, Debug, AzBuf, Default)] +pub struct LastSeenMessagesUpdate { + #[var] + pub messages: u32, + pub acknowledged: FixedBitSet<20>, +} diff --git a/azalea-protocol/src/packets/game/s_chat_ack.rs b/azalea-protocol/src/packets/game/s_chat_ack.rs new file mode 100755 index 00000000..d4b6efd6 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat_ack.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChatAck { + #[var] + pub messages: u32, +} diff --git a/azalea-protocol/src/packets/game/s_chat_command.rs b/azalea-protocol/src/packets/game/s_chat_command.rs new file mode 100755 index 00000000..4fdab9f9 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat_command.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChatCommand { + pub command: String, +} diff --git a/azalea-protocol/src/packets/game/s_chat_command_signed.rs b/azalea-protocol/src/packets/game/s_chat_command_signed.rs new file mode 100755 index 00000000..c20f3c6d --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat_command_signed.rs @@ -0,0 +1,20 @@ +use azalea_buf::AzBuf; +use azalea_crypto::MessageSignature; +use azalea_protocol_macros::ServerboundGamePacket; + +use super::s_chat::LastSeenMessagesUpdate; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChatCommandSigned { + pub command: String, + pub timestamp: u64, + pub salt: u64, + pub argument_signatures: Vec, + pub last_seen_messages: LastSeenMessagesUpdate, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct ArgumentSignature { + pub name: String, + pub signature: MessageSignature, +} diff --git a/azalea-protocol/src/packets/game/s_chat_preview.rs b/azalea-protocol/src/packets/game/s_chat_preview.rs new file mode 100755 index 00000000..3d2bf34e --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat_preview.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChatPreview { + pub query_id: i32, + pub query: String, +} diff --git a/azalea-protocol/src/packets/game/s_chat_session_update.rs b/azalea-protocol/src/packets/game/s_chat_session_update.rs new file mode 100644 index 00000000..f3499983 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chat_session_update.rs @@ -0,0 +1,21 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChatSessionUpdate { + pub chat_session: RemoteChatSessionData, +} + +#[derive(Clone, Debug, PartialEq, Eq, AzBuf)] +pub struct RemoteChatSessionData { + pub session_id: Uuid, + pub profile_public_key: ProfilePublicKeyData, +} + +#[derive(Clone, Debug, AzBuf, PartialEq, Eq)] +pub struct ProfilePublicKeyData { + pub expires_at: u64, + pub key: Vec, + pub key_signature: Vec, +} diff --git a/azalea-protocol/src/packets/game/s_chunk_batch_received.rs b/azalea-protocol/src/packets/game/s_chunk_batch_received.rs new file mode 100644 index 00000000..faa50932 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_chunk_batch_received.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundChunkBatchReceived { + pub desired_chunks_per_tick: f32, +} diff --git a/azalea-protocol/src/packets/game/s_client_command.rs b/azalea-protocol/src/packets/game/s_client_command.rs new file mode 100755 index 00000000..5742bdb4 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_client_command.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundClientCommand { + pub action: Action, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + PerformRespawn = 0, + RequestStats = 1, +} diff --git a/azalea-protocol/src/packets/game/s_client_information.rs b/azalea-protocol/src/packets/game/s_client_information.rs new file mode 100755 index 00000000..5861212c --- /dev/null +++ b/azalea-protocol/src/packets/game/s_client_information.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::common::client_information::ClientInformation; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundClientInformation { + pub information: ClientInformation, +} diff --git a/azalea-protocol/src/packets/game/s_client_tick_end.rs b/azalea-protocol/src/packets/game/s_client_tick_end.rs new file mode 100644 index 00000000..d8d93049 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_client_tick_end.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundClientTickEnd {} diff --git a/azalea-protocol/src/packets/game/s_command_suggestion.rs b/azalea-protocol/src/packets/game/s_command_suggestion.rs new file mode 100755 index 00000000..2e52a969 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_command_suggestion.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundCommandSuggestion { + #[var] + pub id: u32, + pub command: String, +} diff --git a/azalea-protocol/src/packets/game/s_configuration_acknowledged.rs b/azalea-protocol/src/packets/game/s_configuration_acknowledged.rs new file mode 100644 index 00000000..58e27abb --- /dev/null +++ b/azalea-protocol/src/packets/game/s_configuration_acknowledged.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundConfigurationAcknowledged {} diff --git a/azalea-protocol/src/packets/game/s_container_button_click.rs b/azalea-protocol/src/packets/game/s_container_button_click.rs new file mode 100755 index 00000000..909772f3 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_container_button_click.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundContainerButtonClick { + pub container_id: u8, + pub button_id: u8, +} diff --git a/azalea-protocol/src/packets/game/s_container_click.rs b/azalea-protocol/src/packets/game/s_container_click.rs new file mode 100755 index 00000000..a6dee697 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_container_click.rs @@ -0,0 +1,17 @@ +use std::collections::HashMap; + +use azalea_buf::AzBuf; +use azalea_inventory::{operations::ClickType, ItemStack}; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundContainerClick { + pub container_id: u8, + #[var] + pub state_id: u32, + pub slot_num: i16, + pub button_num: u8, + pub click_type: ClickType, + pub changed_slots: HashMap, + pub carried_item: ItemStack, +} diff --git a/azalea-protocol/src/packets/game/s_container_close.rs b/azalea-protocol/src/packets/game/s_container_close.rs new file mode 100755 index 00000000..1cb88eab --- /dev/null +++ b/azalea-protocol/src/packets/game/s_container_close.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundContainerClose { + pub container_id: u8, +} diff --git a/azalea-protocol/src/packets/game/s_container_slot_state_changed.rs b/azalea-protocol/src/packets/game/s_container_slot_state_changed.rs new file mode 100644 index 00000000..73ac0280 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_container_slot_state_changed.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundContainerSlotStateChanged { + #[var] + pub slot_id: u32, + #[var] + pub container_id: u32, + pub new_state: bool, +} diff --git a/azalea-protocol/src/packets/game/s_cookie_response.rs b/azalea-protocol/src/packets/game/s_cookie_response.rs new file mode 100644 index 00000000..5159d72e --- /dev/null +++ b/azalea-protocol/src/packets/game/s_cookie_response.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundCookieResponse { + pub key: ResourceLocation, + pub payload: Option>, +} diff --git a/azalea-protocol/src/packets/game/s_custom_payload.rs b/azalea-protocol/src/packets/game/s_custom_payload.rs new file mode 100755 index 00000000..b32f1d24 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_custom_payload.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_buf::UnsizedByteArray; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundCustomPayload { + pub identifier: ResourceLocation, + pub data: UnsizedByteArray, +} diff --git a/azalea-protocol/src/packets/game/s_debug_sample_subscription.rs b/azalea-protocol/src/packets/game/s_debug_sample_subscription.rs new file mode 100644 index 00000000..45051793 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_debug_sample_subscription.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundDebugSampleSubscription { + pub sample_type: RemoteDebugSampleType, +} + +#[derive(Clone, Copy, Debug, AzBuf)] +pub enum RemoteDebugSampleType { + TickTime, +} diff --git a/azalea-protocol/src/packets/game/s_edit_book.rs b/azalea-protocol/src/packets/game/s_edit_book.rs new file mode 100755 index 00000000..af05a7cd --- /dev/null +++ b/azalea-protocol/src/packets/game/s_edit_book.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundEditBook { + #[var] + pub slot: u32, + pub pages: Vec, + pub title: Option, +} diff --git a/azalea-protocol/src/packets/game/s_entity_tag_query.rs b/azalea-protocol/src/packets/game/s_entity_tag_query.rs new file mode 100644 index 00000000..619e9e54 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_entity_tag_query.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundEntityTagQuery { + #[var] + pub transaction_id: u32, + #[var] + pub entity_id: u32, +} diff --git a/azalea-protocol/src/packets/game/s_interact.rs b/azalea-protocol/src/packets/game/s_interact.rs new file mode 100755 index 00000000..cdd9cba5 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_interact.rs @@ -0,0 +1,86 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar}; +use azalea_core::position::Vec3; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::BufReadError; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundInteract { + #[var] + pub entity_id: u32, + pub action: ActionType, + /// Whether the player is sneaking + pub using_secondary_action: bool, +} + +#[derive(Clone, Copy, Debug)] +pub enum ActionType { + Interact { + hand: InteractionHand, + }, + Attack, + InteractAt { + location: Vec3, + hand: InteractionHand, + }, +} + +impl AzaleaWrite for ActionType { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + ActionType::Interact { hand } => { + 0u32.azalea_write_var(buf)?; + hand.azalea_write(buf)?; + } + ActionType::Attack => { + 1u32.azalea_write_var(buf)?; + } + ActionType::InteractAt { location, hand } => { + 2u32.azalea_write_var(buf)?; + (location.x as f32).azalea_write(buf)?; + (location.y as f32).azalea_write(buf)?; + (location.z as f32).azalea_write(buf)?; + hand.azalea_write(buf)?; + } + } + Ok(()) + } +} + +impl AzaleaRead for ActionType { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let action_type = u32::azalea_read_var(buf)?; + match action_type { + 0 => { + let hand = InteractionHand::azalea_read(buf)?; + Ok(ActionType::Interact { hand }) + } + 1 => Ok(ActionType::Attack), + 2 => { + let x = f32::azalea_read(buf)?; + let y = f32::azalea_read(buf)?; + let z = f32::azalea_read(buf)?; + let hand = InteractionHand::azalea_read(buf)?; + Ok(ActionType::InteractAt { + location: Vec3 { + x: f64::from(x), + y: f64::from(y), + z: f64::from(z), + }, + hand, + }) + } + _ => Err(BufReadError::UnexpectedEnumVariant { + id: action_type as i32, + }), + } + } +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum InteractionHand { + MainHand = 0, + OffHand = 1, +} diff --git a/azalea-protocol/src/packets/game/s_jigsaw_generate.rs b/azalea-protocol/src/packets/game/s_jigsaw_generate.rs new file mode 100755 index 00000000..4a3b58ce --- /dev/null +++ b/azalea-protocol/src/packets/game/s_jigsaw_generate.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundJigsawGenerate { + pub pos: BlockPos, + #[var] + pub levels: u32, + pub keep_jigsaws: bool, +} diff --git a/azalea-protocol/src/packets/game/s_keep_alive.rs b/azalea-protocol/src/packets/game/s_keep_alive.rs new file mode 100755 index 00000000..a6806a92 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_keep_alive.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundKeepAlive { + pub id: u64, +} diff --git a/azalea-protocol/src/packets/game/s_lock_difficulty.rs b/azalea-protocol/src/packets/game/s_lock_difficulty.rs new file mode 100755 index 00000000..72acb705 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_lock_difficulty.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundLockDifficulty { + pub locked: bool, +} diff --git a/azalea-protocol/src/packets/game/s_move_player_pos.rs b/azalea-protocol/src/packets/game/s_move_player_pos.rs new file mode 100755 index 00000000..2e2ec0c5 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_move_player_pos.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundMovePlayerPos { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/s_move_player_pos_rot.rs b/azalea-protocol/src/packets/game/s_move_player_pos_rot.rs new file mode 100755 index 00000000..cb0e0633 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_move_player_pos_rot.rs @@ -0,0 +1,12 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundMovePlayerPosRot { + pub x: f64, + pub y: f64, + pub z: f64, + pub y_rot: f32, + pub x_rot: f32, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/s_move_player_rot.rs b/azalea-protocol/src/packets/game/s_move_player_rot.rs new file mode 100755 index 00000000..c3cda3ea --- /dev/null +++ b/azalea-protocol/src/packets/game/s_move_player_rot.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundMovePlayerRot { + pub y_rot: f32, + pub x_rot: f32, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/s_move_player_status_only.rs b/azalea-protocol/src/packets/game/s_move_player_status_only.rs new file mode 100755 index 00000000..155841f0 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_move_player_status_only.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundMovePlayerStatusOnly { + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/s_move_vehicle.rs b/azalea-protocol/src/packets/game/s_move_vehicle.rs new file mode 100755 index 00000000..0452c9b0 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_move_vehicle.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundMoveVehicle { + pub x: f64, + pub y: f64, + pub z: f64, + pub y_rot: f32, + pub x_rot: f32, +} diff --git a/azalea-protocol/src/packets/game/s_paddle_boat.rs b/azalea-protocol/src/packets/game/s_paddle_boat.rs new file mode 100755 index 00000000..eed7addc --- /dev/null +++ b/azalea-protocol/src/packets/game/s_paddle_boat.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPaddleBoat { + pub left: bool, + pub right: bool, +} diff --git a/azalea-protocol/src/packets/game/s_pick_item.rs b/azalea-protocol/src/packets/game/s_pick_item.rs new file mode 100755 index 00000000..289da6e7 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_pick_item.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPickItem { + #[var] + pub slot: u32, +} diff --git a/azalea-protocol/src/packets/game/s_pick_item_from_entity.rs b/azalea-protocol/src/packets/game/s_pick_item_from_entity.rs new file mode 100644 index 00000000..42032063 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_pick_item_from_entity.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPickItemFromEntity { + #[var] + pub id: u32, + pub include_data: bool, +} diff --git a/azalea-protocol/src/packets/game/s_ping_request.rs b/azalea-protocol/src/packets/game/s_ping_request.rs new file mode 100755 index 00000000..1ea7550f --- /dev/null +++ b/azalea-protocol/src/packets/game/s_ping_request.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPingRequest { + pub time: u64, +} diff --git a/azalea-protocol/src/packets/game/s_place_recipe.rs b/azalea-protocol/src/packets/game/s_place_recipe.rs new file mode 100755 index 00000000..33456948 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_place_recipe.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPlaceRecipe { + pub container_id: u8, + pub recipe: ResourceLocation, + pub shift_down: bool, +} diff --git a/azalea-protocol/src/packets/game/s_player_abilities.rs b/azalea-protocol/src/packets/game/s_player_abilities.rs new file mode 100755 index 00000000..fdf2d8a4 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_player_abilities.rs @@ -0,0 +1,31 @@ +use std::io::Cursor; + +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::bitset::FixedBitSet; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::BufReadError; + +#[derive(Clone, Debug, ServerboundGamePacket)] +pub struct ServerboundPlayerAbilities { + pub is_flying: bool, +} + +impl AzaleaRead for ServerboundPlayerAbilities { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<2>::azalea_read(buf)?; + Ok(Self { + is_flying: set.index(1), + }) + } +} + +impl AzaleaWrite for ServerboundPlayerAbilities { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<2>::new(); + if self.is_flying { + set.set(1); + } + set.azalea_write(buf) + } +} diff --git a/azalea-protocol/src/packets/game/s_player_action.rs b/azalea-protocol/src/packets/game/s_player_action.rs new file mode 100755 index 00000000..5b65b746 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_player_action.rs @@ -0,0 +1,24 @@ +use azalea_buf::AzBuf; +use azalea_core::direction::Direction; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPlayerAction { + pub action: Action, + pub pos: BlockPos, + pub direction: Direction, + #[var] + pub sequence: u32, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + StartDestroyBlock = 0, + AbortDestroyBlock = 1, + StopDestroyBlock = 2, + DropAllItems = 3, + DropItem = 4, + ReleaseUseItem = 5, + SwapItemWithOffhand = 6, +} diff --git a/azalea-protocol/src/packets/game/s_player_command.rs b/azalea-protocol/src/packets/game/s_player_command.rs new file mode 100755 index 00000000..72a92310 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_player_command.rs @@ -0,0 +1,24 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPlayerCommand { + #[var] + pub id: u32, + pub action: Action, + #[var] + pub data: u32, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + PressShiftKey = 0, + ReleaseShiftKey = 1, + StopSleeping = 2, + StartSprinting = 3, + StopSprinting = 4, + StartRidingJump = 5, + StopRidingJump = 6, + OpenInventory = 7, + StartFallFlying = 8, +} diff --git a/azalea-protocol/src/packets/game/s_player_input.rs b/azalea-protocol/src/packets/game/s_player_input.rs new file mode 100755 index 00000000..bd4ba970 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_player_input.rs @@ -0,0 +1,60 @@ +use std::io::Cursor; + +use azalea_buf::BufReadError; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::bitset::FixedBitSet; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, ServerboundGamePacket)] +pub struct ServerboundPlayerInput { + pub forward: bool, + pub backward: bool, + pub left: bool, + pub right: bool, + pub jump: bool, + pub shift: bool, + pub sprint: bool, +} + +impl AzaleaRead for ServerboundPlayerInput { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<7>::azalea_read(buf)?; + Ok(Self { + forward: set.index(0), + backward: set.index(1), + left: set.index(2), + right: set.index(3), + jump: set.index(4), + shift: set.index(5), + sprint: set.index(6), + }) + } +} + +impl AzaleaWrite for ServerboundPlayerInput { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<7>::new(); + if self.forward { + set.set(0); + } + if self.backward { + set.set(1); + } + if self.left { + set.set(2); + } + if self.right { + set.set(3); + } + if self.jump { + set.set(4); + } + if self.shift { + set.set(5); + } + if self.sprint { + set.set(6); + } + set.azalea_write(buf) + } +} diff --git a/azalea-protocol/src/packets/game/s_player_loaded.rs b/azalea-protocol/src/packets/game/s_player_loaded.rs new file mode 100644 index 00000000..3e809b26 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_player_loaded.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPlayerLoaded; diff --git a/azalea-protocol/src/packets/game/s_pong.rs b/azalea-protocol/src/packets/game/s_pong.rs new file mode 100755 index 00000000..10ce0fb7 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_pong.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundPong { + pub id: u32, +} diff --git a/azalea-protocol/src/packets/game/s_recipe_book_change_settings.rs b/azalea-protocol/src/packets/game/s_recipe_book_change_settings.rs new file mode 100755 index 00000000..a31ca173 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_recipe_book_change_settings.rs @@ -0,0 +1,17 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundRecipeBookChangeSettings { + pub book_type: RecipeBookType, + pub is_open: bool, + pub is_filtering: bool, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum RecipeBookType { + Crafting = 0, + Furnace = 1, + BlastFurnace = 2, + Smoker = 3, +} diff --git a/azalea-protocol/src/packets/game/s_recipe_book_seen_recipe.rs b/azalea-protocol/src/packets/game/s_recipe_book_seen_recipe.rs new file mode 100755 index 00000000..9eeffde9 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_recipe_book_seen_recipe.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundRecipeBookSeenRecipe { + pub recipe: ResourceLocation, +} diff --git a/azalea-protocol/src/packets/game/s_rename_item.rs b/azalea-protocol/src/packets/game/s_rename_item.rs new file mode 100755 index 00000000..4c913ba0 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_rename_item.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundRenameItem { + pub name: String, +} diff --git a/azalea-protocol/src/packets/game/s_resource_pack.rs b/azalea-protocol/src/packets/game/s_resource_pack.rs new file mode 100755 index 00000000..7bdb7bb4 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_resource_pack.rs @@ -0,0 +1,20 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundResourcePack { + pub id: Uuid, + pub action: Action, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Action { + SuccessfullyLoaded = 0, + Declined = 1, + FailedDownload = 2, + Accepted = 3, + InvalidUrl = 4, + FailedReload = 5, + Discarded = 6, +} diff --git a/azalea-protocol/src/packets/game/s_seen_advancements.rs b/azalea-protocol/src/packets/game/s_seen_advancements.rs new file mode 100755 index 00000000..f46411f0 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_seen_advancements.rs @@ -0,0 +1,41 @@ +use std::io::Cursor; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite}; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::BufReadError; + +#[derive(Clone, Debug, ServerboundGamePacket)] +pub struct ServerboundSeenAdvancements { + pub action: Action, + pub tab: Option, +} + +#[derive(AzBuf, Clone, Copy, Debug, Eq, PartialEq)] +pub enum Action { + OpenedTab = 0, + ClosedScreen = 1, +} + +impl AzaleaRead for ServerboundSeenAdvancements { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let action = Action::azalea_read(buf)?; + let tab = if action == Action::OpenedTab { + Some(ResourceLocation::azalea_read(buf)?) + } else { + None + }; + Ok(Self { action, tab }) + } +} + +impl AzaleaWrite for ServerboundSeenAdvancements { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + self.action.azalea_write(buf)?; + if let Some(tab) = &self.tab { + tab.azalea_write(buf)?; + } + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/s_select_trade.rs b/azalea-protocol/src/packets/game/s_select_trade.rs new file mode 100755 index 00000000..e0cc8aab --- /dev/null +++ b/azalea-protocol/src/packets/game/s_select_trade.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSelectTrade { + #[var] + pub item: u32, +} diff --git a/azalea-protocol/src/packets/game/s_set_beacon.rs b/azalea-protocol/src/packets/game/s_set_beacon.rs new file mode 100755 index 00000000..b0b911a1 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_beacon.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetBeacon { + #[var] + pub primary: Option, + #[var] + pub secondary: Option, +} diff --git a/azalea-protocol/src/packets/game/s_set_carried_item.rs b/azalea-protocol/src/packets/game/s_set_carried_item.rs new file mode 100755 index 00000000..5efa2d44 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_carried_item.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetCarriedItem { + pub slot: u16, +} diff --git a/azalea-protocol/src/packets/game/s_set_command_block.rs b/azalea-protocol/src/packets/game/s_set_command_block.rs new file mode 100755 index 00000000..dacb79de --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_command_block.rs @@ -0,0 +1,63 @@ +use std::io::Cursor; + +use azalea_buf::{AzBuf, AzaleaRead, BufReadError}; +use azalea_core::{bitset::FixedBitSet, position::BlockPos}; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::AzaleaWrite; + +#[derive(Clone, Debug, ServerboundGamePacket)] +pub struct ServerboundSetCommandBlock { + pub pos: BlockPos, + pub command: String, + pub mode: Mode, + + pub track_output: bool, + pub conditional: bool, + pub automatic: bool, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Mode { + Sequence = 0, + Auto = 1, + Redstone = 2, +} + +impl AzaleaRead for ServerboundSetCommandBlock { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let pos = BlockPos::azalea_read(buf)?; + let command = String::azalea_read(buf)?; + let mode = Mode::azalea_read(buf)?; + + let set = FixedBitSet::<3>::azalea_read(buf)?; + Ok(Self { + pos, + command, + mode, + track_output: set.index(0), + conditional: set.index(1), + automatic: set.index(2), + }) + } +} + +impl AzaleaWrite for ServerboundSetCommandBlock { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + self.pos.azalea_write(buf)?; + self.command.azalea_write(buf)?; + self.mode.azalea_write(buf)?; + + let mut set = FixedBitSet::<3>::new(); + if self.track_output { + set.set(0); + } + if self.conditional { + set.set(1); + } + if self.automatic { + set.set(2); + } + set.azalea_write(buf) + } +} diff --git a/azalea-protocol/src/packets/game/s_set_command_minecart.rs b/azalea-protocol/src/packets/game/s_set_command_minecart.rs new file mode 100755 index 00000000..0431a865 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_command_minecart.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetCommandMinecart { + #[var] + pub entity: u32, + pub command: String, + pub track_output: bool, +} diff --git a/azalea-protocol/src/packets/game/s_set_creative_mode_slot.rs b/azalea-protocol/src/packets/game/s_set_creative_mode_slot.rs new file mode 100755 index 00000000..e4b26a64 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_creative_mode_slot.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_inventory::ItemStack; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetCreativeModeSlot { + pub slot_num: u16, + pub item_stack: ItemStack, +} diff --git a/azalea-protocol/src/packets/game/s_set_jigsaw_block.rs b/azalea-protocol/src/packets/game/s_set_jigsaw_block.rs new file mode 100755 index 00000000..1d97d4c7 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_jigsaw_block.rs @@ -0,0 +1,51 @@ +use std::io::Cursor; +use std::io::Write; + +use azalea_buf::AzBuf; +use azalea_buf::AzaleaRead; +use azalea_core::position::BlockPos; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::AzaleaWrite; +use crate::packets::BufReadError; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetJigsawBlock { + pub pos: BlockPos, + pub name: ResourceLocation, + pub target: ResourceLocation, + pub pool: ResourceLocation, + pub final_state: String, + pub joint: String, + #[var] + pub selection_priority: i32, + #[var] + pub placement_priority: i32, +} + +pub enum JointType { + Rollable, + Aligned, +} + +impl AzaleaRead for JointType { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let name = String::azalea_read(buf)?; + match name.as_str() { + "rollable" => Ok(JointType::Rollable), + "aligned" => Ok(JointType::Aligned), + _ => Err(BufReadError::UnexpectedStringEnumVariant { id: name }), + } + } +} + +impl AzaleaWrite for JointType { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + JointType::Rollable => "rollable".to_string().azalea_write(buf)?, + JointType::Aligned => "aligned".to_string().azalea_write(buf)?, + }; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/s_set_structure_block.rs b/azalea-protocol/src/packets/game/s_set_structure_block.rs new file mode 100755 index 00000000..7f05a3a7 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_set_structure_block.rs @@ -0,0 +1,98 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::AzBuf; +use azalea_buf::{AzaleaRead, AzaleaWrite}; +use azalea_core::{bitset::FixedBitSet, position::BlockPos}; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::BufReadError; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSetStructureBlock { + pub pos: BlockPos, + pub update_type: UpdateType, + pub mode: StructureMode, + pub name: String, + pub offset: BytePosition, + pub size: BytePosition, + pub mirror: Mirror, + pub rotation: Rotation, + pub data: String, + pub integrity: f32, + #[var] + pub seed: u64, + pub flags: Flags, +} + +#[derive(Clone, Debug, AzBuf)] +pub struct BytePosition { + pub x: u8, + pub y: u8, + pub z: u8, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum UpdateType { + UpdateData = 0, + SaveArea = 1, + LoadArea = 2, + ScanArea = 3, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum StructureMode { + Save = 0, + Load = 1, + Corner = 2, + Data = 3, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Mirror { + None = 0, + LeftRight = 1, + FrontBack = 2, +} + +#[derive(AzBuf, Clone, Copy, Debug)] +pub enum Rotation { + None = 0, + Clockwise90 = 1, + Clockwise180 = 2, + Counterclockwise90 = 3, +} + +#[derive(Debug, Clone)] +pub struct Flags { + pub ignore_entities: bool, + pub show_air: bool, + pub show_bounding_box: bool, +} + +impl AzaleaRead for Flags { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let set = FixedBitSet::<3>::azalea_read(buf)?; + Ok(Self { + ignore_entities: set.index(0), + show_air: set.index(1), + show_bounding_box: set.index(2), + }) + } +} + +impl AzaleaWrite for Flags { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let mut set = FixedBitSet::<3>::new(); + if self.ignore_entities { + set.set(0); + } + if self.show_air { + set.set(1); + } + if self.show_bounding_box { + set.set(2); + } + set.azalea_write(buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/game/s_sign_update.rs b/azalea-protocol/src/packets/game/s_sign_update.rs new file mode 100755 index 00000000..c43a0978 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_sign_update.rs @@ -0,0 +1,10 @@ +use azalea_buf::AzBuf; +use azalea_core::position::BlockPos; +use azalea_protocol_macros::ServerboundGamePacket; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSignUpdate { + pub pos: BlockPos, + pub is_front_text: bool, + pub lines: [String; 4], +} diff --git a/azalea-protocol/src/packets/game/s_swing.rs b/azalea-protocol/src/packets/game/s_swing.rs new file mode 100755 index 00000000..68648ac6 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_swing.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::game::s_interact::InteractionHand; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundSwing { + pub hand: InteractionHand, +} diff --git a/azalea-protocol/src/packets/game/s_teleport_to_entity.rs b/azalea-protocol/src/packets/game/s_teleport_to_entity.rs new file mode 100755 index 00000000..e8829530 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_teleport_to_entity.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; +use uuid::Uuid; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundTeleportToEntity { + pub uuid: Uuid, +} diff --git a/azalea-protocol/src/packets/game/s_use_item.rs b/azalea-protocol/src/packets/game/s_use_item.rs new file mode 100755 index 00000000..ac8ae217 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_use_item.rs @@ -0,0 +1,13 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::game::s_interact::InteractionHand; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundUseItem { + pub hand: InteractionHand, + #[var] + pub sequence: u32, + pub yaw: f32, + pub pitch: f32, +} diff --git a/azalea-protocol/src/packets/game/s_use_item_on.rs b/azalea-protocol/src/packets/game/s_use_item_on.rs new file mode 100755 index 00000000..0ad23ad2 --- /dev/null +++ b/azalea-protocol/src/packets/game/s_use_item_on.rs @@ -0,0 +1,74 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; +use azalea_core::{ + direction::Direction, + position::{BlockPos, Vec3}, +}; +use azalea_protocol_macros::ServerboundGamePacket; + +use crate::packets::game::s_interact::InteractionHand; + +#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)] +pub struct ServerboundUseItemOn { + pub hand: InteractionHand, + pub block_hit: BlockHit, + #[var] + pub sequence: u32, +} + +#[derive(Clone, Debug)] +pub struct BlockHit { + /// The block that we clicked. + pub block_pos: BlockPos, + /// The face of the block that was clicked. + pub direction: Direction, + /// The exact coordinates of the world where the block was clicked. In the + /// network, this is transmitted as the difference between the location and + /// block position. + pub location: Vec3, + /// Whether the player's head is inside of a block. + pub inside: bool, +} + +impl AzaleaWrite for BlockHit { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.block_pos.azalea_write(buf)?; + self.direction.azalea_write(buf)?; + f32::azalea_write( + &((self.location.x - f64::from(self.block_pos.x)) as f32), + buf, + )?; + f32::azalea_write( + &((self.location.y - f64::from(self.block_pos.y)) as f32), + buf, + )?; + f32::azalea_write( + &((self.location.z - f64::from(self.block_pos.z)) as f32), + buf, + )?; + self.inside.azalea_write(buf)?; + Ok(()) + } +} + +impl AzaleaRead for BlockHit { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let block_pos = BlockPos::azalea_read(buf)?; + let direction = Direction::azalea_read(buf)?; + let cursor_x = f32::azalea_read(buf)?; + let cursor_y = f32::azalea_read(buf)?; + let cursor_z = f32::azalea_read(buf)?; + let inside = bool::azalea_read(buf)?; + Ok(Self { + block_pos, + direction, + location: Vec3 { + x: f64::from(block_pos.x) + f64::from(cursor_x), + y: f64::from(block_pos.y) + f64::from(cursor_y), + z: f64::from(block_pos.z) + f64::from(cursor_z), + }, + inside, + }) + } +} diff --git a/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs b/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs deleted file mode 100755 index 85311e48..00000000 --- a/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundAcceptTeleportationPacket { - #[var] - pub id: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query.rs b/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query.rs deleted file mode 100755 index 4b396a67..00000000 --- a/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundBlockEntityTagQuery { - #[var] - pub transaction_id: i32, - pub pos: BlockPos, -} diff --git a/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query_packet.rs b/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query_packet.rs deleted file mode 100644 index d8856647..00000000 --- a/azalea-protocol/src/packets/game/serverbound_block_entity_tag_query_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundBlockEntityTagQueryPacket { - #[var] - pub transaction_id: u32, - pub pos: BlockPos, -} diff --git a/azalea-protocol/src/packets/game/serverbound_change_difficulty_packet.rs b/azalea-protocol/src/packets/game/serverbound_change_difficulty_packet.rs deleted file mode 100755 index 460de5b2..00000000 --- a/azalea-protocol/src/packets/game/serverbound_change_difficulty_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::difficulty::Difficulty; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChangeDifficultyPacket { - pub difficulty: Difficulty, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs deleted file mode 100755 index eaf285cb..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatAckPacket { - #[var] - pub messages: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs deleted file mode 100755 index 23a796d8..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatCommandPacket { - pub command: String, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_command_signed_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_command_signed_packet.rs deleted file mode 100755 index f64b79cc..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_command_signed_packet.rs +++ /dev/null @@ -1,20 +0,0 @@ -use azalea_buf::McBuf; -use azalea_crypto::MessageSignature; -use azalea_protocol_macros::ServerboundGamePacket; - -use super::serverbound_chat_packet::LastSeenMessagesUpdate; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatCommandSignedPacket { - pub command: String, - pub timestamp: u64, - pub salt: u64, - pub argument_signatures: Vec, - pub last_seen_messages: LastSeenMessagesUpdate, -} - -#[derive(Clone, Debug, McBuf)] -pub struct ArgumentSignature { - pub name: String, - pub signature: MessageSignature, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_packet.rs deleted file mode 100755 index e0a1726c..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_packet.rs +++ /dev/null @@ -1,20 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::bitset::FixedBitSet; -use azalea_crypto::MessageSignature; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatPacket { - pub message: String, - pub timestamp: u64, - pub salt: u64, - pub signature: Option, - pub last_seen_messages: LastSeenMessagesUpdate, -} - -#[derive(Clone, Debug, McBuf, Default)] -pub struct LastSeenMessagesUpdate { - #[var] - pub messages: u32, - pub acknowledged: FixedBitSet<20>, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_preview_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_preview_packet.rs deleted file mode 100755 index 50b44728..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_preview_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatPreviewPacket { - pub query_id: i32, - pub query: String, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_session_update_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_session_update_packet.rs deleted file mode 100644 index e56d2bc6..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chat_session_update_packet.rs +++ /dev/null @@ -1,21 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChatSessionUpdatePacket { - pub chat_session: RemoteChatSessionData, -} - -#[derive(Clone, Debug, PartialEq, Eq, McBuf)] -pub struct RemoteChatSessionData { - pub session_id: Uuid, - pub profile_public_key: ProfilePublicKeyData, -} - -#[derive(Clone, Debug, McBuf, PartialEq, Eq)] -pub struct ProfilePublicKeyData { - pub expires_at: u64, - pub key: Vec, - pub key_signature: Vec, -} diff --git a/azalea-protocol/src/packets/game/serverbound_chunk_batch_received_packet.rs b/azalea-protocol/src/packets/game/serverbound_chunk_batch_received_packet.rs deleted file mode 100644 index 9f18f967..00000000 --- a/azalea-protocol/src/packets/game/serverbound_chunk_batch_received_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundChunkBatchReceivedPacket { - pub desired_chunks_per_tick: f32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_client_command_packet.rs b/azalea-protocol/src/packets/game/serverbound_client_command_packet.rs deleted file mode 100755 index 2f360cb9..00000000 --- a/azalea-protocol/src/packets/game/serverbound_client_command_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundClientCommandPacket { - pub action: Action, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - PerformRespawn = 0, - RequestStats = 1, -} diff --git a/azalea-protocol/src/packets/game/serverbound_client_information_packet.rs b/azalea-protocol/src/packets/game/serverbound_client_information_packet.rs deleted file mode 100755 index 37a101f5..00000000 --- a/azalea-protocol/src/packets/game/serverbound_client_information_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::configuration::serverbound_client_information_packet::ClientInformation; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundClientInformationPacket { - pub information: ClientInformation, -} diff --git a/azalea-protocol/src/packets/game/serverbound_client_tick_end_packet.rs b/azalea-protocol/src/packets/game/serverbound_client_tick_end_packet.rs deleted file mode 100644 index c843066e..00000000 --- a/azalea-protocol/src/packets/game/serverbound_client_tick_end_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundTickEndPacket {} diff --git a/azalea-protocol/src/packets/game/serverbound_command_suggestion_packet.rs b/azalea-protocol/src/packets/game/serverbound_command_suggestion_packet.rs deleted file mode 100755 index 0cca3ceb..00000000 --- a/azalea-protocol/src/packets/game/serverbound_command_suggestion_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundCommandSuggestionPacket { - #[var] - pub id: u32, - pub command: String, -} diff --git a/azalea-protocol/src/packets/game/serverbound_configuration_acknowledged_packet.rs b/azalea-protocol/src/packets/game/serverbound_configuration_acknowledged_packet.rs deleted file mode 100644 index c790972a..00000000 --- a/azalea-protocol/src/packets/game/serverbound_configuration_acknowledged_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundConfigurationAcknowledgedPacket {} diff --git a/azalea-protocol/src/packets/game/serverbound_container_button_click_packet.rs b/azalea-protocol/src/packets/game/serverbound_container_button_click_packet.rs deleted file mode 100755 index 739e7390..00000000 --- a/azalea-protocol/src/packets/game/serverbound_container_button_click_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundContainerButtonClickPacket { - pub container_id: u8, - pub button_id: u8, -} diff --git a/azalea-protocol/src/packets/game/serverbound_container_click_packet.rs b/azalea-protocol/src/packets/game/serverbound_container_click_packet.rs deleted file mode 100755 index e2954720..00000000 --- a/azalea-protocol/src/packets/game/serverbound_container_click_packet.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::collections::HashMap; - -use azalea_buf::McBuf; -use azalea_inventory::{operations::ClickType, ItemSlot}; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundContainerClickPacket { - pub container_id: u8, - #[var] - pub state_id: u32, - pub slot_num: i16, - pub button_num: u8, - pub click_type: ClickType, - pub changed_slots: HashMap, - pub carried_item: ItemSlot, -} diff --git a/azalea-protocol/src/packets/game/serverbound_container_close_packet.rs b/azalea-protocol/src/packets/game/serverbound_container_close_packet.rs deleted file mode 100755 index dbaf59f3..00000000 --- a/azalea-protocol/src/packets/game/serverbound_container_close_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundContainerClosePacket { - pub container_id: u8, -} diff --git a/azalea-protocol/src/packets/game/serverbound_container_slot_state_changed_packet.rs b/azalea-protocol/src/packets/game/serverbound_container_slot_state_changed_packet.rs deleted file mode 100644 index 8a83f4e2..00000000 --- a/azalea-protocol/src/packets/game/serverbound_container_slot_state_changed_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundContainerSlotStateChangedPacket { - #[var] - pub slot_id: u32, - #[var] - pub container_id: u32, - pub new_state: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_cookie_response_packet.rs b/azalea-protocol/src/packets/game/serverbound_cookie_response_packet.rs deleted file mode 100644 index 8ad0f07e..00000000 --- a/azalea-protocol/src/packets/game/serverbound_cookie_response_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundCookieResponsePacket { - pub key: ResourceLocation, - pub payload: Option>, -} diff --git a/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs b/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs deleted file mode 100755 index d5d46627..00000000 --- a/azalea-protocol/src/packets/game/serverbound_custom_payload_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_buf::UnsizedByteArray; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundCustomPayloadPacket { - pub identifier: ResourceLocation, - pub data: UnsizedByteArray, -} diff --git a/azalea-protocol/src/packets/game/serverbound_debug_sample_subscription.rs b/azalea-protocol/src/packets/game/serverbound_debug_sample_subscription.rs deleted file mode 100755 index 236972e0..00000000 --- a/azalea-protocol/src/packets/game/serverbound_debug_sample_subscription.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundDebugSampleSubscription { - pub sample_type: RemoteDebugSampleType, -} - -#[derive(Clone, Copy, Debug, McBuf)] -pub enum RemoteDebugSampleType { - TickTime, -} diff --git a/azalea-protocol/src/packets/game/serverbound_edit_book_packet.rs b/azalea-protocol/src/packets/game/serverbound_edit_book_packet.rs deleted file mode 100755 index 62d4b318..00000000 --- a/azalea-protocol/src/packets/game/serverbound_edit_book_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundEditBookPacket { - #[var] - pub slot: u32, - pub pages: Vec, - pub title: Option, -} diff --git a/azalea-protocol/src/packets/game/serverbound_entity_tag_query.rs b/azalea-protocol/src/packets/game/serverbound_entity_tag_query.rs deleted file mode 100755 index 5b0c7db6..00000000 --- a/azalea-protocol/src/packets/game/serverbound_entity_tag_query.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundEntityTagQuery { - #[var] - pub transaction_id: u32, - #[var] - pub entity_id: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_entity_tag_query_packet.rs b/azalea-protocol/src/packets/game/serverbound_entity_tag_query_packet.rs deleted file mode 100644 index d40a59a6..00000000 --- a/azalea-protocol/src/packets/game/serverbound_entity_tag_query_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundEntityTagQueryPacket { - #[var] - pub transaction_id: u32, - #[var] - pub entity_id: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_interact_packet.rs b/azalea-protocol/src/packets/game/serverbound_interact_packet.rs deleted file mode 100755 index e393920c..00000000 --- a/azalea-protocol/src/packets/game/serverbound_interact_packet.rs +++ /dev/null @@ -1,86 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; -use azalea_core::position::Vec3; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::BufReadError; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundInteractPacket { - #[var] - pub entity_id: u32, - pub action: ActionType, - /// Whether the player is sneaking - pub using_secondary_action: bool, -} - -#[derive(Clone, Copy, Debug)] -pub enum ActionType { - Interact { - hand: InteractionHand, - }, - Attack, - InteractAt { - location: Vec3, - hand: InteractionHand, - }, -} - -impl McBufWritable for ActionType { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - ActionType::Interact { hand } => { - 0u32.var_write_into(buf)?; - hand.write_into(buf)?; - } - ActionType::Attack => { - 1u32.var_write_into(buf)?; - } - ActionType::InteractAt { location, hand } => { - 2u32.var_write_into(buf)?; - (location.x as f32).write_into(buf)?; - (location.y as f32).write_into(buf)?; - (location.z as f32).write_into(buf)?; - hand.write_into(buf)?; - } - } - Ok(()) - } -} - -impl McBufReadable for ActionType { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let action_type = u32::var_read_from(buf)?; - match action_type { - 0 => { - let hand = InteractionHand::read_from(buf)?; - Ok(ActionType::Interact { hand }) - } - 1 => Ok(ActionType::Attack), - 2 => { - let x = f32::read_from(buf)?; - let y = f32::read_from(buf)?; - let z = f32::read_from(buf)?; - let hand = InteractionHand::read_from(buf)?; - Ok(ActionType::InteractAt { - location: Vec3 { - x: f64::from(x), - y: f64::from(y), - z: f64::from(z), - }, - hand, - }) - } - _ => Err(BufReadError::UnexpectedEnumVariant { - id: action_type as i32, - }), - } - } -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum InteractionHand { - MainHand = 0, - OffHand = 1, -} diff --git a/azalea-protocol/src/packets/game/serverbound_jigsaw_generate_packet.rs b/azalea-protocol/src/packets/game/serverbound_jigsaw_generate_packet.rs deleted file mode 100755 index 34fd5985..00000000 --- a/azalea-protocol/src/packets/game/serverbound_jigsaw_generate_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundJigsawGeneratePacket { - pub pos: BlockPos, - #[var] - pub levels: u32, - pub keep_jigsaws: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs b/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs deleted file mode 100755 index 7485e11e..00000000 --- a/azalea-protocol/src/packets/game/serverbound_keep_alive_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundKeepAlivePacket { - pub id: u64, -} diff --git a/azalea-protocol/src/packets/game/serverbound_lock_difficulty_packet.rs b/azalea-protocol/src/packets/game/serverbound_lock_difficulty_packet.rs deleted file mode 100755 index 3c54a16a..00000000 --- a/azalea-protocol/src/packets/game/serverbound_lock_difficulty_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundLockDifficultyPacket { - pub locked: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_pos_packet.rs b/azalea-protocol/src/packets/game/serverbound_move_player_pos_packet.rs deleted file mode 100755 index 4e3face4..00000000 --- a/azalea-protocol/src/packets/game/serverbound_move_player_pos_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundMovePlayerPosPacket { - pub x: f64, - pub y: f64, - pub z: f64, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_pos_rot_packet.rs b/azalea-protocol/src/packets/game/serverbound_move_player_pos_rot_packet.rs deleted file mode 100755 index 0ab9c885..00000000 --- a/azalea-protocol/src/packets/game/serverbound_move_player_pos_rot_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundMovePlayerPosRotPacket { - pub x: f64, - pub y: f64, - pub z: f64, - pub y_rot: f32, - pub x_rot: f32, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_rot_packet.rs b/azalea-protocol/src/packets/game/serverbound_move_player_rot_packet.rs deleted file mode 100755 index 11a77e73..00000000 --- a/azalea-protocol/src/packets/game/serverbound_move_player_rot_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundMovePlayerRotPacket { - pub y_rot: f32, - pub x_rot: f32, - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_status_only_packet.rs b/azalea-protocol/src/packets/game/serverbound_move_player_status_only_packet.rs deleted file mode 100755 index fc91caca..00000000 --- a/azalea-protocol/src/packets/game/serverbound_move_player_status_only_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundMovePlayerStatusOnlyPacket { - pub on_ground: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_move_vehicle_packet.rs b/azalea-protocol/src/packets/game/serverbound_move_vehicle_packet.rs deleted file mode 100755 index 929ba798..00000000 --- a/azalea-protocol/src/packets/game/serverbound_move_vehicle_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundMoveVehiclePacket { - pub x: f64, - pub y: f64, - pub z: f64, - pub y_rot: f32, - pub x_rot: f32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_paddle_boat_packet.rs b/azalea-protocol/src/packets/game/serverbound_paddle_boat_packet.rs deleted file mode 100755 index 2db9ef2e..00000000 --- a/azalea-protocol/src/packets/game/serverbound_paddle_boat_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPaddleBoatPacket { - pub left: bool, - pub right: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_pick_item_packet.rs b/azalea-protocol/src/packets/game/serverbound_pick_item_packet.rs deleted file mode 100755 index 508e710b..00000000 --- a/azalea-protocol/src/packets/game/serverbound_pick_item_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPickItemPacket { - #[var] - pub slot: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_ping_request_packet.rs b/azalea-protocol/src/packets/game/serverbound_ping_request_packet.rs deleted file mode 100755 index 0966e941..00000000 --- a/azalea-protocol/src/packets/game/serverbound_ping_request_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPingRequestPacket { - pub time: u64, -} diff --git a/azalea-protocol/src/packets/game/serverbound_place_recipe_packet.rs b/azalea-protocol/src/packets/game/serverbound_place_recipe_packet.rs deleted file mode 100755 index 03dd833b..00000000 --- a/azalea-protocol/src/packets/game/serverbound_place_recipe_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPlaceRecipePacket { - pub container_id: u8, - pub recipe: ResourceLocation, - pub shift_down: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_player_abilities_packet.rs b/azalea-protocol/src/packets/game/serverbound_player_abilities_packet.rs deleted file mode 100755 index 900d1824..00000000 --- a/azalea-protocol/src/packets/game/serverbound_player_abilities_packet.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::io::Cursor; - -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::bitset::FixedBitSet; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::BufReadError; - -#[derive(Clone, Debug, ServerboundGamePacket)] -pub struct ServerboundPlayerAbilitiesPacket { - pub is_flying: bool, -} - -impl McBufReadable for ServerboundPlayerAbilitiesPacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<2>::read_from(buf)?; - Ok(Self { - is_flying: set.index(1), - }) - } -} - -impl McBufWritable for ServerboundPlayerAbilitiesPacket { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<2>::new(); - if self.is_flying { - set.set(1); - } - set.write_into(buf) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_player_action_packet.rs b/azalea-protocol/src/packets/game/serverbound_player_action_packet.rs deleted file mode 100755 index 6719202f..00000000 --- a/azalea-protocol/src/packets/game/serverbound_player_action_packet.rs +++ /dev/null @@ -1,24 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::direction::Direction; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPlayerActionPacket { - pub action: Action, - pub pos: BlockPos, - pub direction: Direction, - #[var] - pub sequence: u32, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - StartDestroyBlock = 0, - AbortDestroyBlock = 1, - StopDestroyBlock = 2, - DropAllItems = 3, - DropItem = 4, - ReleaseUseItem = 5, - SwapItemWithOffhand = 6, -} diff --git a/azalea-protocol/src/packets/game/serverbound_player_command_packet.rs b/azalea-protocol/src/packets/game/serverbound_player_command_packet.rs deleted file mode 100755 index d7688092..00000000 --- a/azalea-protocol/src/packets/game/serverbound_player_command_packet.rs +++ /dev/null @@ -1,24 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPlayerCommandPacket { - #[var] - pub id: u32, - pub action: Action, - #[var] - pub data: u32, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - PressShiftKey = 0, - ReleaseShiftKey = 1, - StopSleeping = 2, - StartSprinting = 3, - StopSprinting = 4, - StartRidingJump = 5, - StopRidingJump = 6, - OpenInventory = 7, - StartFallFlying = 8, -} diff --git a/azalea-protocol/src/packets/game/serverbound_player_input_packet.rs b/azalea-protocol/src/packets/game/serverbound_player_input_packet.rs deleted file mode 100755 index a461ddf5..00000000 --- a/azalea-protocol/src/packets/game/serverbound_player_input_packet.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::io::Cursor; - -use azalea_buf::BufReadError; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::bitset::FixedBitSet; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, ServerboundGamePacket)] -pub struct ServerboundPlayerInputPacket { - pub forward: bool, - pub backward: bool, - pub left: bool, - pub right: bool, - pub jump: bool, - pub shift: bool, - pub sprint: bool, -} - -impl McBufReadable for ServerboundPlayerInputPacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<7>::read_from(buf)?; - Ok(Self { - forward: set.index(0), - backward: set.index(1), - left: set.index(2), - right: set.index(3), - jump: set.index(4), - shift: set.index(5), - sprint: set.index(6), - }) - } -} - -impl McBufWritable for ServerboundPlayerInputPacket { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<7>::new(); - if self.forward { - set.set(0); - } - if self.backward { - set.set(1); - } - if self.left { - set.set(2); - } - if self.right { - set.set(3); - } - if self.jump { - set.set(4); - } - if self.shift { - set.set(5); - } - if self.sprint { - set.set(6); - } - set.write_into(buf) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_pong_packet.rs b/azalea-protocol/src/packets/game/serverbound_pong_packet.rs deleted file mode 100755 index 17f1ac81..00000000 --- a/azalea-protocol/src/packets/game/serverbound_pong_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundPongPacket { - pub id: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_recipe_book_change_settings_packet.rs b/azalea-protocol/src/packets/game/serverbound_recipe_book_change_settings_packet.rs deleted file mode 100755 index 6b3f015b..00000000 --- a/azalea-protocol/src/packets/game/serverbound_recipe_book_change_settings_packet.rs +++ /dev/null @@ -1,17 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundRecipeBookChangeSettingsPacket { - pub book_type: RecipeBookType, - pub is_open: bool, - pub is_filtering: bool, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum RecipeBookType { - Crafting = 0, - Furnace = 1, - BlastFurnace = 2, - Smoker = 3, -} diff --git a/azalea-protocol/src/packets/game/serverbound_recipe_book_seen_recipe_packet.rs b/azalea-protocol/src/packets/game/serverbound_recipe_book_seen_recipe_packet.rs deleted file mode 100755 index 9923e3a6..00000000 --- a/azalea-protocol/src/packets/game/serverbound_recipe_book_seen_recipe_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundRecipeBookSeenRecipePacket { - pub recipe: ResourceLocation, -} diff --git a/azalea-protocol/src/packets/game/serverbound_rename_item_packet.rs b/azalea-protocol/src/packets/game/serverbound_rename_item_packet.rs deleted file mode 100755 index 8308ac31..00000000 --- a/azalea-protocol/src/packets/game/serverbound_rename_item_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundRenameItemPacket { - pub name: String, -} diff --git a/azalea-protocol/src/packets/game/serverbound_resource_pack_packet.rs b/azalea-protocol/src/packets/game/serverbound_resource_pack_packet.rs deleted file mode 100755 index f285707b..00000000 --- a/azalea-protocol/src/packets/game/serverbound_resource_pack_packet.rs +++ /dev/null @@ -1,20 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundResourcePackPacket { - pub id: Uuid, - pub action: Action, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Action { - SuccessfullyLoaded = 0, - Declined = 1, - FailedDownload = 2, - Accepted = 3, - InvalidUrl = 4, - FailedReload = 5, - Discarded = 6, -} diff --git a/azalea-protocol/src/packets/game/serverbound_seen_advancements_packet.rs b/azalea-protocol/src/packets/game/serverbound_seen_advancements_packet.rs deleted file mode 100755 index 54fd4cc9..00000000 --- a/azalea-protocol/src/packets/game/serverbound_seen_advancements_packet.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::io::Cursor; - -use azalea_buf::{McBuf, McBufReadable, McBufWritable}; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::BufReadError; - -#[derive(Clone, Debug, ServerboundGamePacket)] -pub struct ServerboundSeenAdvancementsPacket { - pub action: Action, - pub tab: Option, -} - -#[derive(McBuf, Clone, Copy, Debug, Eq, PartialEq)] -pub enum Action { - OpenedTab = 0, - ClosedScreen = 1, -} - -impl McBufReadable for ServerboundSeenAdvancementsPacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let action = Action::read_from(buf)?; - let tab = if action == Action::OpenedTab { - Some(ResourceLocation::read_from(buf)?) - } else { - None - }; - Ok(Self { action, tab }) - } -} - -impl McBufWritable for ServerboundSeenAdvancementsPacket { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - self.action.write_into(buf)?; - if let Some(tab) = &self.tab { - tab.write_into(buf)?; - } - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_select_bundle_item_packet.rs b/azalea-protocol/src/packets/game/serverbound_select_bundle_item_packet.rs deleted file mode 100644 index 3a315183..00000000 --- a/azalea-protocol/src/packets/game/serverbound_select_bundle_item_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSelectBundleItemPacket { - #[var] - pub slot_id: i32, - #[var] - pub selected_item_index: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_select_trade_packet.rs b/azalea-protocol/src/packets/game/serverbound_select_trade_packet.rs deleted file mode 100755 index b13e30d5..00000000 --- a/azalea-protocol/src/packets/game/serverbound_select_trade_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSelectTradePacket { - #[var] - pub item: u32, -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_beacon_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_beacon_packet.rs deleted file mode 100755 index db76cb9c..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_beacon_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetBeaconPacket { - #[var] - pub primary: Option, - #[var] - pub secondary: Option, -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_carried_item_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_carried_item_packet.rs deleted file mode 100755 index 044cdeb0..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_carried_item_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetCarriedItemPacket { - pub slot: u16, -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_command_block_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_command_block_packet.rs deleted file mode 100755 index db6557fd..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_command_block_packet.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::io::Cursor; - -use azalea_buf::{BufReadError, McBuf, McBufReadable}; -use azalea_core::{bitset::FixedBitSet, position::BlockPos}; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::McBufWritable; - -#[derive(Clone, Debug, ServerboundGamePacket)] -pub struct ServerboundSetCommandBlockPacket { - pub pos: BlockPos, - pub command: String, - pub mode: Mode, - - pub track_output: bool, - pub conditional: bool, - pub automatic: bool, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Mode { - Sequence = 0, - Auto = 1, - Redstone = 2, -} - -impl McBufReadable for ServerboundSetCommandBlockPacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let pos = BlockPos::read_from(buf)?; - let command = String::read_from(buf)?; - let mode = Mode::read_from(buf)?; - - let set = FixedBitSet::<3>::read_from(buf)?; - Ok(Self { - pos, - command, - mode, - track_output: set.index(0), - conditional: set.index(1), - automatic: set.index(2), - }) - } -} - -impl McBufWritable for ServerboundSetCommandBlockPacket { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - self.pos.write_into(buf)?; - self.command.write_into(buf)?; - self.mode.write_into(buf)?; - - let mut set = FixedBitSet::<3>::new(); - if self.track_output { - set.set(0); - } - if self.conditional { - set.set(1); - } - if self.automatic { - set.set(2); - } - set.write_into(buf) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_command_minecart_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_command_minecart_packet.rs deleted file mode 100755 index 7756c924..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_command_minecart_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetCommandMinecartPacket { - #[var] - pub entity: u32, - pub command: String, - pub track_output: bool, -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_creative_mode_slot_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_creative_mode_slot_packet.rs deleted file mode 100755 index 7730bf5a..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_creative_mode_slot_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_inventory::ItemSlot; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetCreativeModeSlotPacket { - pub slot_num: u16, - pub item_stack: ItemSlot, -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_jigsaw_block_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_jigsaw_block_packet.rs deleted file mode 100755 index 33a82311..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_jigsaw_block_packet.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::io::Cursor; -use std::io::Write; - -use azalea_buf::McBuf; -use azalea_buf::McBufReadable; -use azalea_core::position::BlockPos; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::BufReadError; -use crate::packets::McBufWritable; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetJigsawBlockPacket { - pub pos: BlockPos, - pub name: ResourceLocation, - pub target: ResourceLocation, - pub pool: ResourceLocation, - pub final_state: String, - pub joint: String, - #[var] - pub selection_priority: i32, - #[var] - pub placement_priority: i32, -} - -pub enum JointType { - Rollable, - Aligned, -} - -impl McBufReadable for JointType { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let name = String::read_from(buf)?; - match name.as_str() { - "rollable" => Ok(JointType::Rollable), - "aligned" => Ok(JointType::Aligned), - _ => Err(BufReadError::UnexpectedStringEnumVariant { id: name }), - } - } -} - -impl McBufWritable for JointType { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - match self { - JointType::Rollable => "rollable".to_string().write_into(buf)?, - JointType::Aligned => "aligned".to_string().write_into(buf)?, - }; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_set_structure_block_packet.rs b/azalea-protocol/src/packets/game/serverbound_set_structure_block_packet.rs deleted file mode 100755 index c2872812..00000000 --- a/azalea-protocol/src/packets/game/serverbound_set_structure_block_packet.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::McBuf; -use azalea_buf::{McBufReadable, McBufWritable}; -use azalea_core::{bitset::FixedBitSet, position::BlockPos}; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::BufReadError; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSetStructureBlockPacket { - pub pos: BlockPos, - pub update_type: UpdateType, - pub mode: StructureMode, - pub name: String, - pub offset: BytePosition, - pub size: BytePosition, - pub mirror: Mirror, - pub rotation: Rotation, - pub data: String, - pub integrity: f32, - #[var] - pub seed: u64, - pub flags: Flags, -} - -#[derive(Clone, Debug, McBuf)] -pub struct BytePosition { - pub x: u8, - pub y: u8, - pub z: u8, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum UpdateType { - UpdateData = 0, - SaveArea = 1, - LoadArea = 2, - ScanArea = 3, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum StructureMode { - Save = 0, - Load = 1, - Corner = 2, - Data = 3, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Mirror { - None = 0, - LeftRight = 1, - FrontBack = 2, -} - -#[derive(McBuf, Clone, Copy, Debug)] -pub enum Rotation { - None = 0, - Clockwise90 = 1, - Clockwise180 = 2, - Counterclockwise90 = 3, -} - -#[derive(Debug, Clone)] -pub struct Flags { - pub ignore_entities: bool, - pub show_air: bool, - pub show_bounding_box: bool, -} - -impl McBufReadable for Flags { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let set = FixedBitSet::<3>::read_from(buf)?; - Ok(Self { - ignore_entities: set.index(0), - show_air: set.index(1), - show_bounding_box: set.index(2), - }) - } -} - -impl McBufWritable for Flags { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let mut set = FixedBitSet::<3>::new(); - if self.ignore_entities { - set.set(0); - } - if self.show_air { - set.set(1); - } - if self.show_bounding_box { - set.set(2); - } - set.write_into(buf)?; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_sign_update_packet.rs b/azalea-protocol/src/packets/game/serverbound_sign_update_packet.rs deleted file mode 100755 index 0547c783..00000000 --- a/azalea-protocol/src/packets/game/serverbound_sign_update_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::position::BlockPos; -use azalea_protocol_macros::ServerboundGamePacket; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSignUpdatePacket { - pub pos: BlockPos, - pub is_front_text: bool, - pub lines: [String; 4], -} diff --git a/azalea-protocol/src/packets/game/serverbound_swing_packet.rs b/azalea-protocol/src/packets/game/serverbound_swing_packet.rs deleted file mode 100755 index 53b4a6c1..00000000 --- a/azalea-protocol/src/packets/game/serverbound_swing_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::game::serverbound_interact_packet::InteractionHand; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundSwingPacket { - pub hand: InteractionHand, -} diff --git a/azalea-protocol/src/packets/game/serverbound_teleport_to_entity_packet.rs b/azalea-protocol/src/packets/game/serverbound_teleport_to_entity_packet.rs deleted file mode 100755 index a7190ea5..00000000 --- a/azalea-protocol/src/packets/game/serverbound_teleport_to_entity_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; -use uuid::Uuid; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundTeleportToEntityPacket { - pub uuid: Uuid, -} diff --git a/azalea-protocol/src/packets/game/serverbound_use_item_on_packet.rs b/azalea-protocol/src/packets/game/serverbound_use_item_on_packet.rs deleted file mode 100755 index 66048327..00000000 --- a/azalea-protocol/src/packets/game/serverbound_use_item_on_packet.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; -use azalea_core::{ - direction::Direction, - position::{BlockPos, Vec3}, -}; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::game::serverbound_interact_packet::InteractionHand; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundUseItemOnPacket { - pub hand: InteractionHand, - pub block_hit: BlockHit, - #[var] - pub sequence: u32, -} - -#[derive(Clone, Debug)] -pub struct BlockHit { - /// The block that we clicked. - pub block_pos: BlockPos, - /// The face of the block that was clicked. - pub direction: Direction, - /// The exact coordinates of the world where the block was clicked. In the - /// network, this is transmitted as the difference between the location and - /// block position. - pub location: Vec3, - /// Whether the player's head is inside of a block. - pub inside: bool, -} - -impl McBufWritable for BlockHit { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.block_pos.write_into(buf)?; - self.direction.write_into(buf)?; - f32::write_into( - &((self.location.x - f64::from(self.block_pos.x)) as f32), - buf, - )?; - f32::write_into( - &((self.location.y - f64::from(self.block_pos.y)) as f32), - buf, - )?; - f32::write_into( - &((self.location.z - f64::from(self.block_pos.z)) as f32), - buf, - )?; - self.inside.write_into(buf)?; - Ok(()) - } -} - -impl McBufReadable for BlockHit { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let block_pos = BlockPos::read_from(buf)?; - let direction = Direction::read_from(buf)?; - let cursor_x = f32::read_from(buf)?; - let cursor_y = f32::read_from(buf)?; - let cursor_z = f32::read_from(buf)?; - let inside = bool::read_from(buf)?; - Ok(Self { - block_pos, - direction, - location: Vec3 { - x: f64::from(block_pos.x) + f64::from(cursor_x), - y: f64::from(block_pos.y) + f64::from(cursor_y), - z: f64::from(block_pos.z) + f64::from(cursor_z), - }, - inside, - }) - } -} diff --git a/azalea-protocol/src/packets/game/serverbound_use_item_packet.rs b/azalea-protocol/src/packets/game/serverbound_use_item_packet.rs deleted file mode 100755 index b9f12f23..00000000 --- a/azalea-protocol/src/packets/game/serverbound_use_item_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundGamePacket; - -use crate::packets::game::serverbound_interact_packet::InteractionHand; - -#[derive(Clone, Debug, McBuf, ServerboundGamePacket)] -pub struct ServerboundUseItemPacket { - pub hand: InteractionHand, - #[var] - pub sequence: u32, - pub yaw: f32, - pub pitch: f32, -} diff --git a/azalea-protocol/src/packets/handshake/mod.rs b/azalea-protocol/src/packets/handshake/mod.rs new file mode 100755 index 00000000..90a312e7 --- /dev/null +++ b/azalea-protocol/src/packets/handshake/mod.rs @@ -0,0 +1,12 @@ +// NOTE: This file is generated automatically by codegen/packet.py. +// Don't edit it directly! + +use azalea_protocol_macros::declare_state_packets; + +declare_state_packets!(HandshakePacket, + Clientbound => [ + ], + Serverbound => [ + intention, + ] +); diff --git a/azalea-protocol/src/packets/handshake/s_intention.rs b/azalea-protocol/src/packets/handshake/s_intention.rs new file mode 100755 index 00000000..566ada30 --- /dev/null +++ b/azalea-protocol/src/packets/handshake/s_intention.rs @@ -0,0 +1,15 @@ +use std::hash::Hash; + +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundHandshakePacket; + +use crate::packets::ClientIntention; + +#[derive(Hash, Clone, Debug, AzBuf, ServerboundHandshakePacket)] +pub struct ServerboundIntention { + #[var] + pub protocol_version: i32, + pub hostname: String, + pub port: u16, + pub intention: ClientIntention, +} diff --git a/azalea-protocol/src/packets/handshaking/client_intention_packet.rs b/azalea-protocol/src/packets/handshaking/client_intention_packet.rs deleted file mode 100755 index c0b694c8..00000000 --- a/azalea-protocol/src/packets/handshaking/client_intention_packet.rs +++ /dev/null @@ -1,15 +0,0 @@ -use std::hash::Hash; - -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundHandshakePacket; - -use crate::packets::ClientIntention; - -#[derive(Hash, Clone, Debug, McBuf, ServerboundHandshakePacket)] -pub struct ClientIntentionPacket { - #[var] - pub protocol_version: i32, - pub hostname: String, - pub port: u16, - pub intention: ClientIntention, -} diff --git a/azalea-protocol/src/packets/handshaking/mod.rs b/azalea-protocol/src/packets/handshaking/mod.rs deleted file mode 100755 index f2e8810e..00000000 --- a/azalea-protocol/src/packets/handshaking/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub mod client_intention_packet; - -use azalea_protocol_macros::declare_state_packets; - -declare_state_packets!( - HandshakePacket, - Serverbound => { - 0x00: client_intention_packet::ClientIntentionPacket, - }, - Clientbound => {} -); diff --git a/azalea-protocol/src/packets/login/c_cookie_request.rs b/azalea-protocol/src/packets/login/c_cookie_request.rs new file mode 100755 index 00000000..d0bb0cd7 --- /dev/null +++ b/azalea-protocol/src/packets/login/c_cookie_request.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundLoginPacket)] +pub struct ClientboundCookieRequest { + pub key: ResourceLocation, +} diff --git a/azalea-protocol/src/packets/login/c_custom_query.rs b/azalea-protocol/src/packets/login/c_custom_query.rs new file mode 100755 index 00000000..80c698e6 --- /dev/null +++ b/azalea-protocol/src/packets/login/c_custom_query.rs @@ -0,0 +1,13 @@ +use std::hash::Hash; + +use azalea_buf::{AzBuf, UnsizedByteArray}; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ClientboundLoginPacket; + +#[derive(Hash, Clone, Debug, AzBuf, ClientboundLoginPacket)] +pub struct ClientboundCustomQuery { + #[var] + pub transaction_id: u32, + pub identifier: ResourceLocation, + pub data: UnsizedByteArray, +} diff --git a/azalea-protocol/src/packets/login/c_hello.rs b/azalea-protocol/src/packets/login/c_hello.rs new file mode 100755 index 00000000..6011ec23 --- /dev/null +++ b/azalea-protocol/src/packets/login/c_hello.rs @@ -0,0 +1,11 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundLoginPacket)] +pub struct ClientboundHello { + #[limit(20)] + pub server_id: String, + pub public_key: Vec, + pub challenge: Vec, + pub should_authenticate: bool, +} diff --git a/azalea-protocol/src/packets/login/c_login_compression.rs b/azalea-protocol/src/packets/login/c_login_compression.rs new file mode 100755 index 00000000..c53e3829 --- /dev/null +++ b/azalea-protocol/src/packets/login/c_login_compression.rs @@ -0,0 +1,10 @@ +use std::hash::Hash; + +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundLoginPacket; + +#[derive(Hash, Clone, Debug, ClientboundLoginPacket, AzBuf)] +pub struct ClientboundLoginCompression { + #[var] + pub compression_threshold: i32, +} diff --git a/azalea-protocol/src/packets/login/c_login_disconnect.rs b/azalea-protocol/src/packets/login/c_login_disconnect.rs new file mode 100755 index 00000000..a0e50aa4 --- /dev/null +++ b/azalea-protocol/src/packets/login/c_login_disconnect.rs @@ -0,0 +1,32 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundLoginPacket; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, ClientboundLoginPacket)] +pub struct ClientboundLoginDisconnect { + pub reason: FormattedText, +} + +impl AzaleaRead for ClientboundLoginDisconnect { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let disconnect_string = String::azalea_read(buf)?; + let disconnect_json: serde_json::Value = serde_json::from_str(disconnect_string.as_str())?; + + Ok(ClientboundLoginDisconnect { + reason: FormattedText::deserialize(disconnect_json)?, + }) + } +} + +impl AzaleaWrite for ClientboundLoginDisconnect { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let status_string = FormattedText::serialize(&self.reason, serde_json::value::Serializer) + .unwrap() + .to_string(); + status_string.azalea_write(buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/login/c_login_finished.rs b/azalea-protocol/src/packets/login/c_login_finished.rs new file mode 100755 index 00000000..482ea53f --- /dev/null +++ b/azalea-protocol/src/packets/login/c_login_finished.rs @@ -0,0 +1,8 @@ +use azalea_auth::game_profile::GameProfile; +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundLoginPacket)] +pub struct ClientboundLoginFinished { + pub game_profile: GameProfile, +} diff --git a/azalea-protocol/src/packets/login/clientbound_cookie_request_packet.rs b/azalea-protocol/src/packets/login/clientbound_cookie_request_packet.rs deleted file mode 100755 index 27ea0c09..00000000 --- a/azalea-protocol/src/packets/login/clientbound_cookie_request_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)] -pub struct ClientboundCookieRequestPacket { - pub key: FormattedText, -} diff --git a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs deleted file mode 100755 index 75993fd9..00000000 --- a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::hash::Hash; - -use azalea_buf::{McBuf, UnsizedByteArray}; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ClientboundLoginPacket; - -#[derive(Hash, Clone, Debug, McBuf, ClientboundLoginPacket)] -pub struct ClientboundCustomQueryPacket { - #[var] - pub transaction_id: u32, - pub identifier: ResourceLocation, - pub data: UnsizedByteArray, -} diff --git a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs deleted file mode 100755 index 9beb499c..00000000 --- a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs +++ /dev/null @@ -1,12 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)] -pub struct ClientboundHelloPacket { - // TODO: make this len thing work - // #[len(20)] - pub server_id: String, - pub public_key: Vec, - pub challenge: Vec, - pub should_authenticate: bool, -} diff --git a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs deleted file mode 100755 index 4b8fb0c8..00000000 --- a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::hash::Hash; - -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundLoginPacket; - -#[derive(Hash, Clone, Debug, ClientboundLoginPacket, McBuf)] -pub struct ClientboundLoginCompressionPacket { - #[var] - pub compression_threshold: i32, -} diff --git a/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs deleted file mode 100755 index 416ec63b..00000000 --- a/azalea-protocol/src/packets/login/clientbound_login_disconnect_packet.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundLoginPacket; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, ClientboundLoginPacket)] -pub struct ClientboundLoginDisconnectPacket { - pub reason: FormattedText, -} - -impl McBufReadable for ClientboundLoginDisconnectPacket { - fn read_from( - buf: &mut Cursor<&[u8]>, - ) -> Result { - let disconnect_string = String::read_from(buf)?; - let disconnect_json: serde_json::Value = serde_json::from_str(disconnect_string.as_str())?; - - Ok(ClientboundLoginDisconnectPacket { - reason: FormattedText::deserialize(disconnect_json)?, - }) - } -} - -impl McBufWritable for ClientboundLoginDisconnectPacket { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let status_string = FormattedText::serialize(&self.reason, serde_json::value::Serializer) - .unwrap() - .to_string(); - status_string.write_into(buf)?; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/login/clientbound_login_finished_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_finished_packet.rs deleted file mode 100755 index f885f67f..00000000 --- a/azalea-protocol/src/packets/login/clientbound_login_finished_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_auth::game_profile::GameProfile; -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)] -pub struct ClientboundLoginFinishedPacket { - pub game_profile: GameProfile, -} diff --git a/azalea-protocol/src/packets/login/mod.rs b/azalea-protocol/src/packets/login/mod.rs index 3d218cc1..9edf50cf 100755 --- a/azalea-protocol/src/packets/login/mod.rs +++ b/azalea-protocol/src/packets/login/mod.rs @@ -1,32 +1,22 @@ -pub mod clientbound_cookie_request_packet; -pub mod clientbound_custom_query_packet; -pub mod clientbound_hello_packet; -pub mod clientbound_login_compression_packet; -pub mod clientbound_login_disconnect_packet; -pub mod clientbound_login_finished_packet; -pub mod serverbound_cookie_response_packet; -pub mod serverbound_custom_query_answer_packet; -pub mod serverbound_hello_packet; -pub mod serverbound_key_packet; -pub mod serverbound_login_acknowledged_packet; +// NOTE: This file is generated automatically by codegen/packet.py. +// Don't edit it directly! use azalea_protocol_macros::declare_state_packets; -declare_state_packets!( - LoginPacket, - Serverbound => { - 0x00: serverbound_hello_packet::ServerboundHelloPacket, - 0x01: serverbound_key_packet::ServerboundKeyPacket, - 0x02: serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket, - 0x03: serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket, - 0x04: serverbound_cookie_response_packet::ServerboundCookieResponsePacket, - }, - Clientbound => { - 0x00: clientbound_login_disconnect_packet::ClientboundLoginDisconnectPacket, - 0x01: clientbound_hello_packet::ClientboundHelloPacket, - 0x02: clientbound_login_finished_packet::ClientboundLoginFinishedPacket, - 0x03: clientbound_login_compression_packet::ClientboundLoginCompressionPacket, - 0x04: clientbound_custom_query_packet::ClientboundCustomQueryPacket, - 0x05: clientbound_cookie_request_packet::ClientboundCookieRequestPacket, - } +declare_state_packets!(LoginPacket, + Clientbound => [ + login_disconnect, + hello, + login_finished, + login_compression, + custom_query, + cookie_request, + ], + Serverbound => [ + hello, + key, + custom_query_answer, + login_acknowledged, + cookie_response, + ] ); diff --git a/azalea-protocol/src/packets/login/s_cookie_response.rs b/azalea-protocol/src/packets/login/s_cookie_response.rs new file mode 100755 index 00000000..5e757600 --- /dev/null +++ b/azalea-protocol/src/packets/login/s_cookie_response.rs @@ -0,0 +1,9 @@ +use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; +use azalea_protocol_macros::ServerboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundCookieResponse { + pub key: ResourceLocation, + pub payload: Option>, +} diff --git a/azalea-protocol/src/packets/login/s_custom_query.rs b/azalea-protocol/src/packets/login/s_custom_query.rs new file mode 100755 index 00000000..39ecdcef --- /dev/null +++ b/azalea-protocol/src/packets/login/s_custom_query.rs @@ -0,0 +1,9 @@ +use azalea_buf::{AzBuf, UnsizedByteArray}; +use azalea_protocol_macros::ServerboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundCustomQuery { + #[var] + pub transaction_id: u32, + pub data: Option, +} diff --git a/azalea-protocol/src/packets/login/s_custom_query_answer.rs b/azalea-protocol/src/packets/login/s_custom_query_answer.rs new file mode 100644 index 00000000..34820294 --- /dev/null +++ b/azalea-protocol/src/packets/login/s_custom_query_answer.rs @@ -0,0 +1,11 @@ +use std::hash::Hash; + +use azalea_buf::{AzBuf, UnsizedByteArray}; +use azalea_protocol_macros::ServerboundLoginPacket; + +#[derive(Hash, Clone, Debug, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundCustomQueryAnswer { + #[var] + pub transaction_id: u32, + pub data: Option, +} diff --git a/azalea-protocol/src/packets/login/s_hello.rs b/azalea-protocol/src/packets/login/s_hello.rs new file mode 100755 index 00000000..bae1947b --- /dev/null +++ b/azalea-protocol/src/packets/login/s_hello.rs @@ -0,0 +1,31 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundLoginPacket; +use uuid::Uuid; + +#[derive(Clone, Debug, PartialEq, Eq, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundHello { + #[limit(16)] + pub name: String, + pub profile_id: Uuid, +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::{AzaleaRead, AzaleaWrite}; + + use super::*; + + #[test] + fn test_read_write() { + let packet = ServerboundHello { + name: "test".to_string(), + profile_id: Uuid::nil(), + }; + let mut buf: Vec = Vec::new(); + packet.azalea_write(&mut buf).unwrap(); + let packet2 = ServerboundHello::azalea_read(&mut Cursor::new(&buf)).unwrap(); + assert_eq!(packet, packet2); + } +} diff --git a/azalea-protocol/src/packets/login/s_key.rs b/azalea-protocol/src/packets/login/s_key.rs new file mode 100755 index 00000000..1b96d445 --- /dev/null +++ b/azalea-protocol/src/packets/login/s_key.rs @@ -0,0 +1,8 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundKey { + pub key_bytes: Vec, + pub encrypted_challenge: Vec, +} diff --git a/azalea-protocol/src/packets/login/s_login_acknowledged.rs b/azalea-protocol/src/packets/login/s_login_acknowledged.rs new file mode 100644 index 00000000..e36648b6 --- /dev/null +++ b/azalea-protocol/src/packets/login/s_login_acknowledged.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundLoginPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundLoginPacket)] +pub struct ServerboundLoginAcknowledged {} diff --git a/azalea-protocol/src/packets/login/serverbound_cookie_response_packet.rs b/azalea-protocol/src/packets/login/serverbound_cookie_response_packet.rs deleted file mode 100755 index 2074e2e7..00000000 --- a/azalea-protocol/src/packets/login/serverbound_cookie_response_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::McBuf; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol_macros::ServerboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)] -pub struct ServerboundCookieResponsePacket { - pub key: ResourceLocation, - pub payload: Option>, -} diff --git a/azalea-protocol/src/packets/login/serverbound_custom_query_answer_packet.rs b/azalea-protocol/src/packets/login/serverbound_custom_query_answer_packet.rs deleted file mode 100644 index fe9460a2..00000000 --- a/azalea-protocol/src/packets/login/serverbound_custom_query_answer_packet.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::hash::Hash; - -use azalea_buf::{McBuf, UnsizedByteArray}; -use azalea_protocol_macros::ServerboundLoginPacket; - -#[derive(Hash, Clone, Debug, McBuf, ServerboundLoginPacket)] -pub struct ServerboundCustomQueryAnswerPacket { - #[var] - pub transaction_id: u32, - pub data: Option, -} diff --git a/azalea-protocol/src/packets/login/serverbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/serverbound_custom_query_packet.rs deleted file mode 100755 index 1d1885cf..00000000 --- a/azalea-protocol/src/packets/login/serverbound_custom_query_packet.rs +++ /dev/null @@ -1,9 +0,0 @@ -use azalea_buf::{McBuf, UnsizedByteArray}; -use azalea_protocol_macros::ServerboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)] -pub struct ServerboundCustomQueryPacket { - #[var] - pub transaction_id: u32, - pub data: Option, -} diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs deleted file mode 100755 index 51ff1830..00000000 --- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs +++ /dev/null @@ -1,30 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundLoginPacket; -use uuid::Uuid; - -#[derive(Clone, Debug, PartialEq, Eq, McBuf, ServerboundLoginPacket)] -pub struct ServerboundHelloPacket { - pub name: String, - pub profile_id: Uuid, -} - -#[cfg(test)] -mod tests { - use std::io::Cursor; - - use azalea_buf::{McBufReadable, McBufWritable}; - - use super::*; - - #[test] - fn test_read_write() { - let packet = ServerboundHelloPacket { - name: "test".to_string(), - profile_id: Uuid::nil(), - }; - let mut buf: Vec = Vec::new(); - packet.write_into(&mut buf).unwrap(); - let packet2 = ServerboundHelloPacket::read_from(&mut Cursor::new(&buf)).unwrap(); - assert_eq!(packet, packet2); - } -} diff --git a/azalea-protocol/src/packets/login/serverbound_key_packet.rs b/azalea-protocol/src/packets/login/serverbound_key_packet.rs deleted file mode 100755 index dc0abeac..00000000 --- a/azalea-protocol/src/packets/login/serverbound_key_packet.rs +++ /dev/null @@ -1,8 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)] -pub struct ServerboundKeyPacket { - pub key_bytes: Vec, - pub encrypted_challenge: Vec, -} diff --git a/azalea-protocol/src/packets/login/serverbound_login_acknowledged_packet.rs b/azalea-protocol/src/packets/login/serverbound_login_acknowledged_packet.rs deleted file mode 100644 index c242a494..00000000 --- a/azalea-protocol/src/packets/login/serverbound_login_acknowledged_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundLoginPacket; - -#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)] -pub struct ServerboundLoginAcknowledgedPacket {} diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs index 1dabe175..14ae7c71 100755 --- a/azalea-protocol/src/packets/mod.rs +++ b/azalea-protocol/src/packets/mod.rs @@ -1,20 +1,18 @@ pub mod common; -pub mod configuration; +pub mod config; pub mod game; -pub mod handshaking; +pub mod handshake; pub mod login; pub mod status; use std::io::{Cursor, Write}; -use azalea_buf::{BufReadError, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_buf::{AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use crate::read::ReadPacketError; -// TODO: rename the packet files to just like clientbound_add_entity instead of -// clientbound_add_entity_packet - pub const PROTOCOL_VERSION: i32 = 768; +pub const VERSION_NAME: &str = "1.21.3"; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ConnectionProtocol { @@ -39,7 +37,7 @@ impl ConnectionProtocol { } } -/// An enum of packets for a certain protocol +/// An enum of packets for a certain protocol. pub trait ProtocolPacket where Self: Sized, @@ -52,6 +50,10 @@ where fn write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>; } +pub trait Packet { + fn into_variant(self) -> Protocol; +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ClientIntention { Status = 1, @@ -81,16 +83,16 @@ impl From for ConnectionProtocol { } } -impl azalea_buf::McBufReadable for ClientIntention { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let id = i32::var_read_from(buf)?; +impl azalea_buf::AzaleaRead for ClientIntention { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let id = i32::azalea_read_var(buf)?; id.try_into() .map_err(|_| BufReadError::UnexpectedEnumVariant { id }) } } -impl McBufWritable for ClientIntention { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - (*self as i32).var_write_into(buf) +impl AzaleaWrite for ClientIntention { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (*self as i32).azalea_write_var(buf) } } diff --git a/azalea-protocol/src/packets/status/c_pong_response.rs b/azalea-protocol/src/packets/status/c_pong_response.rs new file mode 100755 index 00000000..34a5e73b --- /dev/null +++ b/azalea-protocol/src/packets/status/c_pong_response.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ClientboundStatusPacket; + +#[derive(Clone, Debug, AzBuf, ClientboundStatusPacket)] +pub struct ClientboundPongResponse { + pub time: u64, +} diff --git a/azalea-protocol/src/packets/status/c_status_response.rs b/azalea-protocol/src/packets/status/c_status_response.rs new file mode 100755 index 00000000..b30c75be --- /dev/null +++ b/azalea-protocol/src/packets/status/c_status_response.rs @@ -0,0 +1,61 @@ +use std::io::{Cursor, Write}; + +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; +use azalea_chat::FormattedText; +use azalea_protocol_macros::ClientboundStatusPacket; +use serde::{Deserialize, Serialize}; +use serde_json::value::Serializer; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Version { + pub name: String, + pub protocol: i32, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct SamplePlayer { + pub id: String, + pub name: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Players { + pub max: i32, + pub online: i32, + #[serde(default)] + pub sample: Vec, +} + +// the entire packet is just json, which is why it has deserialize +#[derive(Clone, Debug, Serialize, Deserialize, ClientboundStatusPacket)] +pub struct ClientboundStatusResponse { + pub description: FormattedText, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub favicon: Option, + pub players: Players, + pub version: Version, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "enforcesSecureChat")] + pub enforces_secure_chat: Option, +} + +impl AzaleaRead for ClientboundStatusResponse { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let status_string = String::azalea_read(buf)?; + let status_json: serde_json::Value = serde_json::from_str(status_string.as_str())?; + + Ok(ClientboundStatusResponse::deserialize(status_json)?) + } +} + +impl AzaleaWrite for ClientboundStatusResponse { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + let status_string = ClientboundStatusResponse::serialize(self, Serializer) + .unwrap() + .to_string(); + status_string.azalea_write(buf)?; + Ok(()) + } +} diff --git a/azalea-protocol/src/packets/status/clientbound_pong_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_pong_response_packet.rs deleted file mode 100755 index 8c8a7bb1..00000000 --- a/azalea-protocol/src/packets/status/clientbound_pong_response_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ClientboundStatusPacket; - -#[derive(Clone, Debug, McBuf, ClientboundStatusPacket)] -pub struct ClientboundPongResponsePacket { - pub time: u64, -} diff --git a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs deleted file mode 100755 index 1316894e..00000000 --- a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::io::{Cursor, Write}; - -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; -use azalea_chat::FormattedText; -use azalea_protocol_macros::ClientboundStatusPacket; -use serde::{Deserialize, Serialize}; -use serde_json::value::Serializer; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Version { - pub name: String, - pub protocol: i32, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SamplePlayer { - pub id: String, - pub name: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Players { - pub max: i32, - pub online: i32, - #[serde(default)] - pub sample: Vec, -} - -// the entire packet is just json, which is why it has deserialize -#[derive(Clone, Debug, Serialize, Deserialize, ClientboundStatusPacket)] -pub struct ClientboundStatusResponsePacket { - pub description: FormattedText, - #[serde(default)] - #[serde(skip_serializing_if = "Option::is_none")] - pub favicon: Option, - pub players: Players, - pub version: Version, - #[serde(default)] - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(rename = "enforcesSecureChat")] - pub enforces_secure_chat: Option, -} - -impl McBufReadable for ClientboundStatusResponsePacket { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let status_string = String::read_from(buf)?; - let status_json: serde_json::Value = serde_json::from_str(status_string.as_str())?; - - Ok(ClientboundStatusResponsePacket::deserialize(status_json)?) - } -} - -impl McBufWritable for ClientboundStatusResponsePacket { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - let status_string = ClientboundStatusResponsePacket::serialize(self, Serializer) - .unwrap() - .to_string(); - status_string.write_into(buf)?; - Ok(()) - } -} diff --git a/azalea-protocol/src/packets/status/mod.rs b/azalea-protocol/src/packets/status/mod.rs index 3c70c9b1..335600e3 100755 --- a/azalea-protocol/src/packets/status/mod.rs +++ b/azalea-protocol/src/packets/status/mod.rs @@ -1,18 +1,15 @@ -pub mod clientbound_pong_response_packet; -pub mod clientbound_status_response_packet; -pub mod serverbound_ping_request_packet; -pub mod serverbound_status_request_packet; +// NOTE: This file is generated automatically by codegen/packet.py. +// Don't edit it directly! use azalea_protocol_macros::declare_state_packets; -declare_state_packets!( - StatusPacket, - Serverbound => { - 0x00: serverbound_status_request_packet::ServerboundStatusRequestPacket, - 0x01: serverbound_ping_request_packet::ServerboundPingRequestPacket, - }, - Clientbound => { - 0x00: clientbound_status_response_packet::ClientboundStatusResponsePacket, - 0x01: clientbound_pong_response_packet::ClientboundPongResponsePacket, - } +declare_state_packets!(StatusPacket, + Clientbound => [ + status_response, + pong_response, + ], + Serverbound => [ + status_request, + ping_request, + ] ); diff --git a/azalea-protocol/src/packets/status/s_ping_request.rs b/azalea-protocol/src/packets/status/s_ping_request.rs new file mode 100755 index 00000000..34f2e062 --- /dev/null +++ b/azalea-protocol/src/packets/status/s_ping_request.rs @@ -0,0 +1,7 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundStatusPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundStatusPacket)] +pub struct ServerboundPingRequest { + pub time: u64, +} diff --git a/azalea-protocol/src/packets/status/s_status_request.rs b/azalea-protocol/src/packets/status/s_status_request.rs new file mode 100755 index 00000000..662d74bf --- /dev/null +++ b/azalea-protocol/src/packets/status/s_status_request.rs @@ -0,0 +1,5 @@ +use azalea_buf::AzBuf; +use azalea_protocol_macros::ServerboundStatusPacket; + +#[derive(Clone, Debug, AzBuf, ServerboundStatusPacket)] +pub struct ServerboundStatusRequest {} diff --git a/azalea-protocol/src/packets/status/serverbound_ping_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_ping_request_packet.rs deleted file mode 100755 index c546081c..00000000 --- a/azalea-protocol/src/packets/status/serverbound_ping_request_packet.rs +++ /dev/null @@ -1,7 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundStatusPacket; - -#[derive(Clone, Debug, McBuf, ServerboundStatusPacket)] -pub struct ServerboundPingRequestPacket { - pub time: u64, -} diff --git a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs deleted file mode 100755 index 27fce3bf..00000000 --- a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs +++ /dev/null @@ -1,5 +0,0 @@ -use azalea_buf::McBuf; -use azalea_protocol_macros::ServerboundStatusPacket; - -#[derive(Clone, Debug, McBuf, ServerboundStatusPacket)] -pub struct ServerboundStatusRequestPacket {} diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs index 67ea9aee..d75e3bad 100755 --- a/azalea-protocol/src/read.rs +++ b/azalea-protocol/src/read.rs @@ -6,8 +6,8 @@ use std::{ io::{Cursor, Read}, }; +use azalea_buf::AzaleaReadVar; use azalea_buf::BufReadError; -use azalea_buf::McBufVarReadable; use azalea_crypto::Aes128CfbDec; use bytes::Buf; use bytes::BytesMut; @@ -86,7 +86,7 @@ fn parse_frame(buffer: &mut BytesMut) -> Result { // the packet is all good we read it fully let mut buffer_copy = Cursor::new(&buffer[..]); // Packet Length - let length = match u32::var_read_from(&mut buffer_copy) { + let length = match u32::azalea_read_var(&mut buffer_copy) { Ok(length) => length as usize, Err(err) => match err { BufReadError::Io { source } => return Err(FrameSplitterError::Io { source }), @@ -134,7 +134,7 @@ pub fn deserialize_packet( ) -> Result> { // Packet ID let packet_id = - u32::var_read_from(stream).map_err(|e| ReadPacketError::ReadPacketId { source: e })?; + u32::azalea_read_var(stream).map_err(|e| ReadPacketError::ReadPacketId { source: e })?; P::read(packet_id, stream) } @@ -171,7 +171,7 @@ pub fn compression_decoder( compression_threshold: u32, ) -> Result, DecompressionError> { // Data Length - let n = u32::var_read_from(stream)?; + let n = u32::azalea_read_var(stream)?; if n == 0 { // no data size, no compression let mut buf = vec![]; @@ -351,7 +351,7 @@ where } if log::log_enabled!(log::Level::Trace) { - const DO_NOT_CUT_OFF_PACKET_LOGS: bool = false; + const DO_NOT_CUT_OFF_PACKET_LOGS: bool = true; let buf_string: String = { if !DO_NOT_CUT_OFF_PACKET_LOGS && buf.len() > 500 { diff --git a/azalea-protocol/src/write.rs b/azalea-protocol/src/write.rs index 0ec4308b..512d08ad 100755 --- a/azalea-protocol/src/write.rs +++ b/azalea-protocol/src/write.rs @@ -1,8 +1,11 @@ //! Write packets to a stream. -use std::{fmt::Debug, io::Read}; +use std::{ + fmt::Debug, + io::{self, Read}, +}; -use azalea_buf::McBufVarWritable; +use azalea_buf::AzaleaWriteVar; use azalea_crypto::Aes128CfbEnc; use flate2::{bufread::ZlibEncoder, Compression}; use thiserror::Error; @@ -11,31 +14,26 @@ use tracing::trace; use crate::{packets::ProtocolPacket, read::MAXIMUM_UNCOMPRESSED_LENGTH}; -/// Prepend the length of the packet to it. -fn frame_prepender(mut data: Vec) -> Result, std::io::Error> { - let mut buf = Vec::new(); - (data.len() as u32).var_write_into(&mut buf)?; - buf.append(&mut data); - Ok(buf) -} - -#[derive(Error, Debug)] -pub enum PacketEncodeError { - #[error("{0}")] - Io(#[from] std::io::Error), - #[error("Packet too big (is {actual} bytes, should be less than {maximum}): {packet_string}")] - TooBig { - actual: usize, - maximum: usize, - packet_string: String, - }, +pub async fn write_packet( + packet: &P, + stream: &mut W, + compression_threshold: Option, + cipher: &mut Option, +) -> io::Result<()> +where + P: ProtocolPacket + Debug, + W: AsyncWrite + Unpin + Send, +{ + trace!("Sending packet: {packet:?}"); + let raw_packet = serialize_packet(packet).unwrap(); + write_raw_packet(&raw_packet, stream, compression_threshold, cipher).await } pub fn serialize_packet( packet: &P, ) -> Result, PacketEncodeError> { let mut buf = Vec::new(); - packet.id().var_write_into(&mut buf)?; + packet.id().azalea_write_var(&mut buf)?; packet.write(&mut buf)?; if buf.len() > MAXIMUM_UNCOMPRESSED_LENGTH as usize { return Err(PacketEncodeError::TooBig { @@ -47,10 +45,26 @@ pub fn serialize_packet( Ok(buf) } -#[derive(Error, Debug)] -pub enum PacketCompressError { - #[error("{0}")] - Io(#[from] std::io::Error), +pub async fn write_raw_packet( + raw_packet: &[u8], + stream: &mut W, + compression_threshold: Option, + cipher: &mut Option, +) -> io::Result<()> +where + W: AsyncWrite + Unpin + Send, +{ + trace!("Writing raw packet: {raw_packet:?}"); + let mut raw_packet = raw_packet.to_vec(); + if let Some(threshold) = compression_threshold { + raw_packet = compression_encoder(&raw_packet, threshold).unwrap(); + } + raw_packet = frame_prepender(raw_packet).unwrap(); + // if we were given a cipher, encrypt the packet + if let Some(cipher) = cipher { + azalea_crypto::encrypt_packet(cipher, &mut raw_packet); + } + stream.write_all(&raw_packet).await } pub fn compression_encoder( @@ -61,58 +75,48 @@ pub fn compression_encoder( // if it's less than the compression threshold, don't compress if n < compression_threshold as usize { let mut buf = Vec::new(); - 0.var_write_into(&mut buf)?; - std::io::Write::write_all(&mut buf, data)?; + 0_u32.azalea_write_var(&mut buf)?; + io::Write::write_all(&mut buf, data)?; Ok(buf) } else { // otherwise, compress let mut deflater = ZlibEncoder::new(data, Compression::default()); + // write deflated data to buf let mut compressed_data = Vec::new(); deflater.read_to_end(&mut compressed_data)?; // prepend the length let mut len_prepended_compressed_data = Vec::new(); - (data.len() as u32).var_write_into(&mut len_prepended_compressed_data)?; + (data.len() as u32).azalea_write_var(&mut len_prepended_compressed_data)?; len_prepended_compressed_data.append(&mut compressed_data); Ok(len_prepended_compressed_data) } } -pub async fn write_packet( - packet: &P, - stream: &mut W, - compression_threshold: Option, - cipher: &mut Option, -) -> std::io::Result<()> -where - P: ProtocolPacket + Debug, - W: AsyncWrite + Unpin + Send, -{ - trace!("Sending packet: {packet:?}"); - let raw_packet = serialize_packet(packet).unwrap(); - write_raw_packet(&raw_packet, stream, compression_threshold, cipher).await +/// Prepend the length of the packet to it. +fn frame_prepender(mut data: Vec) -> Result, io::Error> { + let mut buf = Vec::new(); + (data.len() as u32).azalea_write_var(&mut buf)?; + buf.append(&mut data); + Ok(buf) } -pub async fn write_raw_packet( - raw_packet: &[u8], - stream: &mut W, - compression_threshold: Option, - cipher: &mut Option, -) -> std::io::Result<()> -where - W: AsyncWrite + Unpin + Send, -{ - trace!("Writing raw packet: {raw_packet:?}"); - let mut raw_packet = raw_packet.to_vec(); - if let Some(threshold) = compression_threshold { - raw_packet = compression_encoder(&raw_packet, threshold).unwrap(); - } - raw_packet = frame_prepender(raw_packet).unwrap(); - // if we were given a cipher, encrypt the packet - if let Some(cipher) = cipher { - azalea_crypto::encrypt_packet(cipher, &mut raw_packet); - } - stream.write_all(&raw_packet).await +#[derive(Error, Debug)] +pub enum PacketEncodeError { + #[error("{0}")] + Io(#[from] io::Error), + #[error("Packet too big (is {actual} bytes, should be less than {maximum}): {packet_string}")] + TooBig { + actual: usize, + maximum: usize, + packet_string: String, + }, +} + +#[derive(Error, Debug)] +pub enum PacketCompressError { + #[error("{0}")] + Io(#[from] io::Error), } diff --git a/azalea-registry/Cargo.toml b/azalea-registry/Cargo.toml index 0ded23c4..1afc14d0 100644 --- a/azalea-registry/Cargo.toml +++ b/azalea-registry/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-registry" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-registry" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-registry/azalea-registry-macros/Cargo.toml b/azalea-registry/azalea-registry-macros/Cargo.toml index ad088b42..147a21ad 100644 --- a/azalea-registry/azalea-registry-macros/Cargo.toml +++ b/azalea-registry/azalea-registry-macros/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-registry-macros" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-registry/azalea-registry-macros" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [lib] proc-macro = true diff --git a/azalea-registry/azalea-registry-macros/src/lib.rs b/azalea-registry/azalea-registry-macros/src/lib.rs index 50a9f199..2b148fd2 100755 --- a/azalea-registry/azalea-registry-macros/src/lib.rs +++ b/azalea-registry/azalea-registry-macros/src/lib.rs @@ -75,7 +75,7 @@ pub fn registry(input: TokenStream) -> TokenStream { let attributes = input.attributes; generated.extend(quote! { #(#attributes)* - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, azalea_buf::McBuf, simdnbt::ToNbtTag, simdnbt::FromNbtTag)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, azalea_buf::AzBuf, simdnbt::ToNbtTag, simdnbt::FromNbtTag)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[repr(u32)] pub enum #name { diff --git a/azalea-registry/src/extra.rs b/azalea-registry/src/extra.rs index d5816e3b..4b7e89a4 100644 --- a/azalea-registry/src/extra.rs +++ b/azalea-registry/src/extra.rs @@ -97,3 +97,37 @@ enum JukeboxSong { CreatorMusicBox => "creator_music_box", } } + +registry! { +enum ChatType { + Chat => "chat", + SayCommand => "say_command", + MsgCommandIncoming => "msg_command_incoming", + MsgCommandOutgoing => "msg_command_outgoing", + TeamMsgCommandIncoming => "team_msg_command_incoming", + TeamMsgCommandOutgoing => "team_msg_command_outgoing", + EmoteCommand => "emote_command", +} +} +impl ChatType { + #[must_use] + pub fn chat_translation_key(self) -> &'static str { + match self { + ChatType::Chat => "chat.type.text", + ChatType::SayCommand => "chat.type.announcement", + ChatType::MsgCommandIncoming => "commands.message.display.incoming", + ChatType::MsgCommandOutgoing => "commands.message.display.outgoing", + ChatType::TeamMsgCommandIncoming => "chat.type.team.text", + ChatType::TeamMsgCommandOutgoing => "chat.type.team.sent", + ChatType::EmoteCommand => "chat.type.emote", + } + } + + #[must_use] + pub fn narrator_translation_key(self) -> &'static str { + match self { + ChatType::EmoteCommand => "chat.type.emote", + _ => "chat.type.text.narrate", + } + } +} diff --git a/azalea-registry/src/lib.rs b/azalea-registry/src/lib.rs index e4287b1c..e1fb2be5 100755 --- a/azalea-registry/src/lib.rs +++ b/azalea-registry/src/lib.rs @@ -11,11 +11,11 @@ pub mod tags; use std::fmt::{self, Debug}; use std::io::{Cursor, Write}; -use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use azalea_registry_macros::registry; pub use extra::*; -pub trait Registry: McBufReadable + McBufWritable +pub trait Registry: AzaleaRead + AzaleaWrite where Self: Sized, { @@ -26,11 +26,11 @@ where /// A registry that might not be present. This is transmitted as a single /// varint in the protocol. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct OptionalRegistry(Option); +pub struct OptionalRegistry(pub Option); -impl McBufReadable for OptionalRegistry { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - Ok(OptionalRegistry(match u32::var_read_from(buf)? { +impl AzaleaRead for OptionalRegistry { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + Ok(OptionalRegistry(match u32::azalea_read_var(buf)? { 0 => None, value => Some( T::from_u32(value - 1) @@ -39,49 +39,49 @@ impl McBufReadable for OptionalRegistry { })) } } -impl McBufWritable for OptionalRegistry { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for OptionalRegistry { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match &self.0 { - None => 0u32.var_write_into(buf), - Some(value) => (value.to_u32() + 1).var_write_into(buf), + None => 0u32.azalea_write_var(buf), + Some(value) => (value.to_u32() + 1).azalea_write_var(buf), } } } /// A registry that will either take an ID or a resource location. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum CustomRegistry { +pub enum CustomRegistry { Direct(D), Custom(C), } -impl McBufReadable for CustomRegistry { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let direct_registry = OptionalRegistry::::read_from(buf)?; +impl AzaleaRead for CustomRegistry { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let direct_registry = OptionalRegistry::::azalea_read(buf)?; if let Some(direct_registry) = direct_registry.0 { return Ok(CustomRegistry::Direct(direct_registry)); } - Ok(CustomRegistry::Custom(C::read_from(buf)?)) + Ok(CustomRegistry::Custom(C::azalea_read(buf)?)) } } -impl McBufWritable for CustomRegistry { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for CustomRegistry { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { CustomRegistry::Direct(direct_registry) => { // write the id + 1 - (direct_registry.to_u32() + 1).var_write_into(buf) + (direct_registry.to_u32() + 1).azalea_write_var(buf) } CustomRegistry::Custom(custom_registry) => { // write 0, then the custom registry - 0u32.var_write_into(buf)?; - custom_registry.write_into(buf) + 0u32.azalea_write_var(buf)?; + custom_registry.azalea_write(buf) } } } } #[derive(Clone, PartialEq)] -pub enum HolderSet { +pub enum HolderSet { Direct { contents: Vec, }, @@ -91,13 +91,13 @@ pub enum HolderSet }, } -impl McBufReadable +impl AzaleaRead for HolderSet { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let size = i32::var_read_from(buf)? - 1; + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let size = i32::azalea_read_var(buf)? - 1; if size == -1 { - let key = ResourceLocation::read_from(buf)?; + let key = ResourceLocation::azalea_read(buf)?; Ok(Self::Named { key, contents: Vec::new(), @@ -105,32 +105,32 @@ impl McBufReadable } else { let mut contents = Vec::new(); for _ in 0..size { - contents.push(D::read_from(buf)?); + contents.push(D::azalea_read(buf)?); } Ok(Self::Direct { contents }) } } } -impl McBufWritable +impl AzaleaWrite for HolderSet { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { Self::Direct { contents } => { - (contents.len() as i32 + 1).var_write_into(buf)?; + (contents.len() as i32 + 1).azalea_write_var(buf)?; for item in contents { - item.write_into(buf)?; + item.azalea_write(buf)?; } } Self::Named { key, .. } => { - 0i32.var_write_into(buf)?; - key.write_into(buf)?; + 0i32.azalea_write_var(buf)?; + key.azalea_write(buf)?; } } Ok(()) } } -impl Debug +impl Debug for HolderSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml index c7b4680b..37bcd5a5 100644 --- a/azalea-world/Cargo.toml +++ b/azalea-world/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea-world" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea-world" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 1709a903..7eb10471 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -8,7 +8,7 @@ use std::{ }; use azalea_block::BlockState; -use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos}; use nohash_hasher::IntMap; use parking_lot::RwLock; @@ -332,7 +332,7 @@ impl Chunk { let section_count = dimension_height / SECTION_HEIGHT; let mut sections = Vec::with_capacity(section_count as usize); for _ in 0..section_count { - let section = Section::read_from(buf)?; + let section = Section::azalea_read(buf)?; sections.push(section); } @@ -416,10 +416,10 @@ pub fn get_block_state_from_sections( Some(section.get(chunk_section_pos)) } -impl McBufWritable for Chunk { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for Chunk { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { for section in &self.sections { - section.write_into(buf)?; + section.azalea_write(buf)?; } Ok(()) } @@ -437,9 +437,9 @@ impl Debug for PartialChunkStorage { } } -impl McBufReadable for Section { - fn read_from(buf: &mut Cursor<&[u8]>) -> Result { - let block_count = u16::read_from(buf)?; +impl AzaleaRead for Section { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result { + let block_count = u16::azalea_read(buf)?; // this is commented out because the vanilla server is wrong // assert!( @@ -467,11 +467,11 @@ impl McBufReadable for Section { } } -impl McBufWritable for Section { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.block_count.write_into(buf)?; - self.states.write_into(buf)?; - self.biomes.write_into(buf)?; +impl AzaleaWrite for Section { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.block_count.azalea_write(buf)?; + self.states.azalea_write(buf)?; + self.biomes.azalea_write(buf)?; Ok(()) } } diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 27e017c4..24dbe47a 100755 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -1,6 +1,6 @@ use std::io::{Cursor, Write}; -use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use azalea_core::math; use tracing::warn; @@ -44,11 +44,11 @@ impl PalettedContainer { buf: &mut Cursor<&[u8]>, container_type: &'static PalettedContainerKind, ) -> Result { - let server_bits_per_entry = u8::read_from(buf)?; + let server_bits_per_entry = u8::azalea_read(buf)?; let palette_type = PaletteKind::from_bits_and_type(server_bits_per_entry, container_type); let palette = palette_type.read(buf)?; let size = container_type.size(); - let data = Vec::::read_from(buf)?; + let data = Vec::::azalea_read(buf)?; // we can only trust the bits per entry that we're sent if there's enough data // that it'd be global. if it's not global, then we have to calculate it @@ -224,11 +224,11 @@ impl PalettedContainer { } } -impl McBufWritable for PalettedContainer { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.bits_per_entry.write_into(buf)?; - self.palette.write_into(buf)?; - self.storage.data.write_into(buf)?; +impl AzaleaWrite for PalettedContainer { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.bits_per_entry.azalea_write(buf)?; + self.palette.azalea_write(buf)?; + self.storage.data.azalea_write(buf)?; Ok(()) } } @@ -264,17 +264,17 @@ impl Palette { } } -impl McBufWritable for Palette { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { +impl AzaleaWrite for Palette { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { Palette::SingleValue(value) => { - value.var_write_into(buf)?; + value.azalea_write_var(buf)?; } Palette::Linear(values) => { - values.var_write_into(buf)?; + values.azalea_write_var(buf)?; } Palette::Hashmap(values) => { - values.var_write_into(buf)?; + values.azalea_write_var(buf)?; } Palette::Global => {} } @@ -301,9 +301,9 @@ impl PaletteKind { pub fn read(&self, buf: &mut Cursor<&[u8]>) -> Result { Ok(match self { - PaletteKind::SingleValue => Palette::SingleValue(u32::var_read_from(buf)?), - PaletteKind::Linear => Palette::Linear(Vec::::var_read_from(buf)?), - PaletteKind::Hashmap => Palette::Hashmap(Vec::::var_read_from(buf)?), + PaletteKind::SingleValue => Palette::SingleValue(u32::azalea_read_var(buf)?), + PaletteKind::Linear => Palette::Linear(Vec::::azalea_read_var(buf)?), + PaletteKind::Hashmap => Palette::Hashmap(Vec::::azalea_read_var(buf)?), PaletteKind::Global => Palette::Global, }) } diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml index 2e2dd345..c0953f54 100644 --- a/azalea/Cargo.toml +++ b/azalea/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" license = "MIT" name = "azalea" repository = "https://github.com/azalea-rs/azalea/tree/main/azalea" -version = "0.10.3+mc1.21.1" +version = "0.10.3+mc1.21.3" [package.metadata.release] pre-release-replacements = [ diff --git a/azalea/examples/steal.rs b/azalea/examples/steal.rs index b0586f19..f64fb8f3 100644 --- a/azalea/examples/steal.rs +++ b/azalea/examples/steal.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use azalea::{prelude::*, BlockPos}; use azalea_inventory::operations::QuickMoveClick; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use parking_lot::Mutex; #[tokio::main] @@ -59,7 +59,7 @@ async fn handle(mut bot: Client, event: Event, state: State) -> anyhow::Result<( .enumerate() { println!("Checking slot {index}: {slot:?}"); - if let ItemSlot::Present(item) = slot { + if let ItemStack::Present(item) = slot { if item.kind == azalea::registry::Item::Diamond { println!("clicking slot ^"); chest.click(QuickMoveClick::Left { slot: index as u16 }); diff --git a/azalea/src/accept_resource_packs.rs b/azalea/src/accept_resource_packs.rs index c9765c77..f62d5ec0 100644 --- a/azalea/src/accept_resource_packs.rs +++ b/azalea/src/accept_resource_packs.rs @@ -3,9 +3,7 @@ use azalea_client::inventory::InventorySet; use azalea_client::packet_handling::game::SendPacketEvent; use azalea_client::packet_handling::{death_event_on_0_health, game::ResourcePackEvent}; use azalea_client::respawn::perform_respawn; -use azalea_protocol::packets::game::serverbound_resource_pack_packet::{ - self, ServerboundResourcePackPacket, -}; +use azalea_protocol::packets::game::s_resource_pack::{self, ServerboundResourcePack}; use bevy_app::Update; use bevy_ecs::prelude::*; @@ -32,21 +30,19 @@ fn accept_resource_pack( mut send_packet_events: EventWriter, ) { for event in events.read() { - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundResourcePackPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundResourcePack { id: event.id, - action: serverbound_resource_pack_packet::Action::Accepted, - } - .get(), - }); - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundResourcePackPacket { + action: s_resource_pack::Action::Accepted, + }, + )); + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundResourcePack { id: event.id, - action: serverbound_resource_pack_packet::Action::SuccessfullyLoaded, - } - .get(), - }); + action: s_resource_pack::Action::SuccessfullyLoaded, + }, + )); } } diff --git a/azalea/src/auto_tool.rs b/azalea/src/auto_tool.rs index e5a627ba..441f9791 100644 --- a/azalea/src/auto_tool.rs +++ b/azalea/src/auto_tool.rs @@ -1,7 +1,7 @@ use azalea_block::{Block, BlockState}; use azalea_client::{inventory::Inventory, Client}; use azalea_entity::{FluidOnEyes, Physics}; -use azalea_inventory::{ItemSlot, Menu}; +use azalea_inventory::{ItemStack, Menu}; use azalea_registry::{DataComponentKind, Fluid}; #[derive(Debug)] @@ -80,7 +80,7 @@ pub fn accurate_best_tool_in_hotbar_for_block( for (i, item_slot) in hotbar_slots.iter().enumerate() { let this_item_speed; match item_slot { - ItemSlot::Empty => { + ItemStack::Empty => { this_item_speed = Some(azalea_entity::mining::get_mine_progress( block.as_ref(), azalea_registry::Item::Air, @@ -89,7 +89,7 @@ pub fn accurate_best_tool_in_hotbar_for_block( physics, )); } - ItemSlot::Present(item_slot) => { + ItemStack::Present(item_slot) => { // lazy way to avoid checking durability since azalea doesn't have durability // data yet if item_slot @@ -119,7 +119,7 @@ pub fn accurate_best_tool_in_hotbar_for_block( // now check every item for (i, item_slot) in hotbar_slots.iter().enumerate() { - if let ItemSlot::Present(item_slot) = item_slot { + if let ItemStack::Present(item_slot) = item_slot { let this_item_speed = azalea_entity::mining::get_mine_progress( block.as_ref(), item_slot.kind, diff --git a/azalea/src/container.rs b/azalea/src/container.rs index 980210ae..df020dbe 100644 --- a/azalea/src/container.rs +++ b/azalea/src/container.rs @@ -7,7 +7,7 @@ use azalea_client::{ Client, }; use azalea_core::position::BlockPos; -use azalea_inventory::{operations::ClickOperation, ItemSlot, Menu}; +use azalea_inventory::{operations::ClickOperation, ItemStack, Menu}; use azalea_protocol::packets::game::ClientboundGamePacket; use bevy_app::{App, Plugin, Update}; use bevy_ecs::{component::Component, prelude::EventReader, system::Commands}; @@ -168,7 +168,7 @@ impl ContainerHandleRef { /// Returns the item slots in the container, not including the player's /// inventory. If the container is closed, this will return `None`. - pub fn contents(&self) -> Option> { + pub fn contents(&self) -> Option> { self.menu().map(|menu| menu.contents()) } @@ -222,7 +222,7 @@ impl ContainerHandle { /// Returns the item slots in the container, not including the player's /// inventory. If the container is closed, this will return `None`. - pub fn contents(&self) -> Option> { + pub fn contents(&self) -> Option> { self.0.contents() } diff --git a/azalea/src/pathfinder/debug.rs b/azalea/src/pathfinder/debug.rs index a5e51cdf..ca08cbc5 100644 --- a/azalea/src/pathfinder/debug.rs +++ b/azalea/src/pathfinder/debug.rs @@ -60,7 +60,7 @@ pub fn debug_render_path_with_particles( let start_vec3 = start.center(); let end_vec3 = end.center(); - let step_count = (start_vec3.distance_to_sqr(&end_vec3).sqrt() * 4.0) as usize; + let step_count = (start_vec3.distance_squared_to(&end_vec3).sqrt() * 4.0) as usize; let target_block_state = chunks.get_block_state(&movement.target).unwrap_or_default(); let above_target_block_state = chunks diff --git a/azalea/src/pathfinder/goals.rs b/azalea/src/pathfinder/goals.rs index 7e33f7d8..531e4036 100644 --- a/azalea/src/pathfinder/goals.rs +++ b/azalea/src/pathfinder/goals.rs @@ -200,7 +200,7 @@ impl Goal for ReachBlockPosGoal { let max_pick_range = 6; let actual_pick_range = 4.5; - let distance = (self.pos - n).length_sqr(); + let distance = (self.pos - n).length_squared(); if distance > max_pick_range * max_pick_range { return false; } diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 611ad5c5..88ae5da0 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -453,7 +453,7 @@ pub fn timeout_movement( // don't timeout if we're mining if let Some(mining) = mining { // also make sure we're close enough to the block that's being mined - if mining.pos.distance_to_sqr(&BlockPos::from(position)) < 6_i32.pow(2) { + if mining.pos.distance_squared_to(&BlockPos::from(position)) < 6_i32.pow(2) { // also reset the last_node_reached_at so we don't timeout after we finish // mining executing_path.last_node_reached_at = Instant::now(); diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs index bb931caf..89ba9acc 100644 --- a/azalea/src/pathfinder/moves/basic.rs +++ b/azalea/src/pathfinder/moves/basic.rs @@ -228,9 +228,10 @@ fn execute_descend_move(mut ctx: ExecuteCtx) { let start_center = start.center(); let center = target.center(); - let horizontal_distance_from_target = (center - position).horizontal_distance_sqr().sqrt(); - let horizontal_distance_from_start = - (start.center() - position).horizontal_distance_sqr().sqrt(); + let horizontal_distance_from_target = (center - position).horizontal_distance_squared().sqrt(); + let horizontal_distance_from_start = (start.center() - position) + .horizontal_distance_squared() + .sqrt(); let dest_ahead = Vec3::new( start_center.x + (center.x - start_center.x) * 1.5, @@ -401,8 +402,9 @@ fn execute_downward_move(mut ctx: ExecuteCtx) { let target_center = target.center(); - let horizontal_distance_from_target = - (target_center - position).horizontal_distance_sqr().sqrt(); + let horizontal_distance_from_target = (target_center - position) + .horizontal_distance_squared() + .sqrt(); if horizontal_distance_from_target > 0.25 { ctx.look_at(target_center); diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs index 28974132..1a435b5f 100644 --- a/azalea/src/pathfinder/moves/mod.rs +++ b/azalea/src/pathfinder/moves/mod.rs @@ -157,7 +157,7 @@ impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_> { /// of the current node first. pub fn mine_while_at_start(&mut self, block: BlockPos) -> bool { let horizontal_distance_from_start = (self.start.center() - self.position) - .horizontal_distance_sqr() + .horizontal_distance_squared() .sqrt(); let at_start_position = BlockPos::from(self.position) == self.start && horizontal_distance_from_start < 0.25; diff --git a/codegen/README.md b/codegen/README.md index 60b881ce..341a432d 100755 --- a/codegen/README.md +++ b/codegen/README.md @@ -4,9 +4,9 @@ The directory name doesn't start with `azalea-` because it's not a Rust crate. ## Requirements -- Python 3.8+ -- Java 17+ -- Maven +- Python 3.8+ +- Java 17+ +- Maven ## Usage @@ -17,19 +17,20 @@ This will create a new file in the `azalea-protocol/src/packets/[state] director ## Updating to a new Minecraft version First, run `python migrate.py [new version]`. This will run a script that automatically updates as much as it can, including: -- Adding, removing, and updating packets in azalea-protocol (limited) -- Updating supported version in README.md -- Updating the `PROTOCOL_VERSION` variable in azalea-protocol -- Generating blocks in azalea-block -- Generating block shapes in azalea-physics -- Generating registries in azalea-registries -- Updating en_us.json in azalea-language -- Generating entity metadata structs and parsers in azalea-world + +- Adding, removing, and updating packets in azalea-protocol (limited) +- Updating supported version in README.md +- Updating the `PROTOCOL_VERSION` variable in azalea-protocol +- Generating blocks in azalea-block +- Generating block shapes in azalea-physics +- Generating registries in azalea-registries +- Updating en_us.json in azalea-language +- Generating entity metadata structs and parsers in azalea-world If you're lucky, that's all you're going to have to do. Look at the diff (`git diff`) and type-check the code (`cargo check`) to make sure everything is right. In the diff, specifically look for new comments that have "TODO". -If a packet is incorrect, you'll want to find it in the Minecraft source. The name of the struct should be the same or similar as the class in the vanilla source. Now, you'll have to manually write the struct for the packet. If the packet existed in the version before and it's just being updated, you can compare against that to see what was updated. Note that if a packet is particularly complicated, you may have to implement McBufReadable and McBufWritable, but most of the time the `#[derive(McBuf)]` macro will be able to generate the impls correctly. Look at other existing packets as reference if you're confused. +If a packet is incorrect, you'll want to find it in the Minecraft source. The name of the struct should be the same or similar as the class in the vanilla source. Now, you'll have to manually write the struct for the packet. If the packet existed in the version before and it's just being updated, you can compare against that to see what was updated. Note that if a packet is particularly complicated, you may have to implement AzaleaRead and AzaleaWrite, but most of the time the `#[derive(AzBuf)]` macro will be able to generate the impls correctly. Look at other existing packets as reference if you're confused. Finally, test by making a bot join a world. Specifically, you'll want to test the things that were updated in the version. Setting the RUST_LOG environment variable to `debug` or `trace` may help you find the source of crashes (trace shows the first few hundred bytes for every packet received so it's typically more useful, but it may log more than you want). @@ -39,9 +40,8 @@ If it all works, make a pull request. If the version you updated to is a snapsho At the time of writing, the following data generators are used: -- [Vanilla data generator](https://wiki.vg/Data_Generators) -- [Burger](https://github.com/mat-1/Burger) -- [PixLyzer](https://gitlab.bixilon.de/bixilon/pixlyzer) +- [Vanilla data generator](https://wiki.vg/Data_Generators) +- [Burger](https://github.com/mat-1/Burger) +- [PixLyzer](https://gitlab.bixilon.de/bixilon/pixlyzer) Some things can be obtained from multiple generators. You should prefer them by the order above (the vanilla generator is the most reliable). - diff --git a/codegen/genblocks.py b/codegen/genblocks.py index 1af0ad10..1024072a 100755 --- a/codegen/genblocks.py +++ b/codegen/genblocks.py @@ -7,25 +7,27 @@ import lib.download import lib.extract import lib.utils -version_id = lib.code.version.get_version_id() +def generate(version_id): + # TODO: pixlyzer is broken so we use old data + shape_datas = lib.extract.get_pixlyzer_data( + '1.20.3-pre4', 'shapes') + pixlyzer_block_datas = lib.extract.get_pixlyzer_data( + '1.20.3-pre4', 'blocks') -# TODO: pixlyzer is broken so we use old data -shape_datas = lib.extract.get_pixlyzer_data( - '1.20.3-pre4', 'shapes') -pixlyzer_block_datas = lib.extract.get_pixlyzer_data( - '1.20.3-pre4', 'blocks') + block_states_report = lib.extract.get_block_states_report(version_id) + registries = lib.extract.get_registries_report(version_id) + ordered_blocks = lib.code.blocks.get_ordered_blocks(registries) -mappings = lib.download.get_mappings_for_version(version_id) -block_states_burger = lib.extract.get_block_states_burger(version_id) -ordered_blocks = lib.extract.get_ordered_blocks_burger(version_id) -block_states_report = lib.extract.get_block_states_report(version_id) + lib.code.blocks.generate_blocks( + block_states_report, pixlyzer_block_datas, ordered_blocks) -lib.code.blocks.generate_blocks( - block_states_burger, block_states_report, pixlyzer_block_datas, ordered_blocks, mappings) + lib.code.shapes.generate_block_shapes( + pixlyzer_block_datas, shape_datas['shapes'], shape_datas['aabbs'], block_states_report) -lib.code.shapes.generate_block_shapes( - pixlyzer_block_datas, shape_datas['shapes'], shape_datas['aabbs'], block_states_report, block_states_burger, mappings) + lib.code.utils.fmt() -lib.code.utils.fmt() + print('Done!') -print('Done!') + +if __name__ == '__main__': + generate(lib.code.version.get_version_id()) diff --git a/codegen/genitemcomponents.py b/codegen/genitemcomponents.py index 32923e7e..73f03081 100644 --- a/codegen/genitemcomponents.py +++ b/codegen/genitemcomponents.py @@ -144,12 +144,12 @@ def add_variant(variant: str): raise ValueError('Couldn\'t find end of match') code = code[:last_line_in_match] + [ - f' DataComponentKind::{variant} => Box::new({variant}::read_from(buf)?),', + f' DataComponentKind::{variant} => Box::new({variant}::azalea_read(buf)?),', ] + code[last_line_in_match:] # now insert the struct code.append('') - code.append('#[derive(Clone, PartialEq, McBuf)]') + code.append('#[derive(Clone, PartialEq, AzBuf)]') code.append(f'pub struct {variant} {{') code.append(' pub todo: todo!(), // see DataComponents.java') code.append('}') diff --git a/codegen/genpackets.py b/codegen/genpackets.py new file mode 100755 index 00000000..0f724aeb --- /dev/null +++ b/codegen/genpackets.py @@ -0,0 +1,18 @@ +import lib.code.version +import lib.code.packet +import lib.code.utils +import lib.download +import lib.extract + +def generate(): + version_id = lib.code.version.get_version_id() + packets_report = lib.extract.get_packets_report(version_id) + + lib.code.packet.set_packets(packets_report) + + lib.code.utils.fmt() + + print('Done!') + +if __name__ == '__main__': + generate() diff --git a/codegen/genregistries.py b/codegen/genregistries.py index b867903b..175d1b20 100755 --- a/codegen/genregistries.py +++ b/codegen/genregistries.py @@ -14,7 +14,6 @@ def generate(version_id: str): lib.code.registry.generate_registries(registries) lib.code.inventory.update_menus(registries['minecraft:menu']['entries']) - block_tags = lib.extract.get_registry_tags(version_id, 'block') item_tags = lib.extract.get_registry_tags(version_id, 'item') fluid_tags = lib.extract.get_registry_tags(version_id, 'fluid') diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py index cda95339..2733093b 100755 --- a/codegen/lib/code/blocks.py +++ b/codegen/lib/code/blocks.py @@ -12,7 +12,7 @@ BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/generated.rs') # - Block: Has properties and states. -def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_datas: dict, ordered_blocks: list[str], mappings: Mappings): +def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blocks: list[str]): with open(BLOCKS_RS_DIR, 'r') as f: existing_code = f.read().splitlines() @@ -25,25 +25,14 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat # This dict looks like { 'FloweringAzaleaLeavesDistance': 'distance' } property_struct_names_to_names = {} for block_id in ordered_blocks: - block_data_burger = blocks_burger[block_id] block_data_report = blocks_report[f'minecraft:{block_id}'] block_properties = {} - for property_name in list(block_data_report.get('properties', {}).keys()): - property_burger = None - for property in block_data_burger.get('states', []): - if property['name'] == property_name: - property_burger = property - break - - property_variants = block_data_report['properties'][property_name] - - if property_burger is None: - print( - f'Warning: The reports have states for a block, but Burger doesn\'t! (missing "{property_name}")', block_data_burger) + for property_id in list(block_data_report.get('properties', {}).keys()): + property_variants = block_data_report['properties'][property_id] property_struct_name = get_property_struct_name( - property_burger, block_data_burger, property_variants, mappings) + block_id, property_id, property_variants) if property_struct_name in properties: if not properties[property_struct_name] == property_variants: @@ -55,7 +44,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat block_properties[property_struct_name] = property_variants - property_struct_names_to_names[property_struct_name] = property_name + property_struct_names_to_names[property_struct_name] = property_id properties.update(block_properties) @@ -67,7 +56,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat # Wall, # Ceiling, # }, - property_name = property_struct_names_to_names[property_struct_name] + property_id = property_struct_names_to_names[property_struct_name] # if the only variants are true and false, we make it unit struct with a boolean instead of an enum if property_variants == ['true', 'false']: @@ -79,38 +68,28 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat property_shape_code += ' }' new_make_block_states_macro_code.append( - f' "{property_name}" => {property_shape_code},') + f' "{property_id}" => {property_shape_code},') new_make_block_states_macro_code.append(' },') # Block codegen new_make_block_states_macro_code.append(' Blocks => {') for block_id in ordered_blocks: - block_data_burger = blocks_burger[block_id] block_data_report = blocks_report['minecraft:' + block_id] block_data_pixlyzer = pixlyzer_block_datas.get(f'minecraft:{block_id}', {}) - block_properties = block_data_burger.get('states', []) - block_properties_burger = block_data_burger.get('states', []) - default_property_variants: dict[str, str] = {} for state in block_data_report['states']: if state.get('default'): default_property_variants = state.get('properties', {}) properties_code = '{' - for property_name in list(block_data_report.get('properties', {}).keys()): - property_burger = None - for property in block_data_burger.get('states', []): - if property['name'] == property_name: - property_burger = property - break - - property_default = default_property_variants.get(property_name) - property_variants = block_data_report['properties'][property_name] + for property_id in list(block_data_report.get('properties', {}).keys()): + property_default = default_property_variants.get(property_id) + property_variants = block_data_report['properties'][property_id] property_struct_name = get_property_struct_name( - property_burger, block_data_burger, property_variants, mappings) + block_id, property_id, property_variants) is_boolean_property = property_variants == ['true', 'false'] @@ -123,7 +102,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat assert property_default is not None - this_property_code = f'"{property_name}": {property_default_type}' + this_property_code = f'"{property_id}": {property_default_type}' properties_code += f'\n {this_property_code},' # if there's nothing inside the properties, keep it in one line @@ -177,8 +156,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat with open(BLOCKS_RS_DIR, 'w') as f: f.write('\n'.join(new_code)) - -def get_property_struct_name(property: Optional[dict], block_data_burger: dict, property_variants: list[str], mappings: Mappings) -> str: +def get_property_struct_name(block_id: str, property_id: str, property_variants: list[str]) -> str: # these are hardcoded because otherwise they cause conflicts # some names inspired by https://github.com/feather-rs/feather/blob/main/feather/blocks/src/generated/table.rs if property_variants == ['north', 'east', 'south', 'west', 'up', 'down']: @@ -205,34 +183,34 @@ def get_property_struct_name(property: Optional[dict], block_data_burger: dict, return 'VaultState' if 'harp' in property_variants and 'didgeridoo' in property_variants: return 'Sound' - - if property is None: - return ''.join(map(to_camel_case, property_variants)) - - if property_variants == ['true', 'false']: - # booleans are weird, so just return the string name minecraft uses - return to_camel_case(property['name']) - - for class_name in [block_data_burger['class']] + block_data_burger['super']: - property_name = mappings.get_field( - class_name, property['field_name']) - if property_name: - break - if property_name is None: - if 'declared_in' in property: - property_name = mappings.get_field( - property['declared_in'], property['field_name']) - if property_name is None: - property_name = property['name'] - assert property_name - property_name = to_camel_case(property_name.lower()) - if property['type'] == 'int': - property_name = to_camel_case( - block_data_burger['text_id']) + property_name - - # if property_variants == ['none', 'low', 'tall']: - + if is_list_of_string_integers(property_variants): + # if the values are all integers, then prepend the block name + return to_camel_case(block_id) + to_camel_case(property_id) if property_variants == ['up', 'side', 'none']: - property_name = 'Wire' + to_camel_case(property_name) - - return property_name + return 'Wire' + to_camel_case(property_id) + if property_variants == ['none', 'low', 'tall']: + return 'Wall' + to_camel_case(property_id) + + return to_camel_case(property_id) + +def is_list_of_string_integers(l: list[str]) -> bool: + return all(map(str.isdigit, l)) + +def get_ordered_blocks(registries_report: dict[str, dict]) -> list[str]: + ''' + Returns a list of block ids (like ['air', 'stone', ...]) ordered by their protocol id. + ''' + blocks_registry = registries_report['minecraft:block'] + + blocks_to_ids = {} + for block_id, value in blocks_registry['entries'].items(): + prefix = 'minecraft:' + assert block_id.startswith(prefix) + block_id = block_id[len(prefix):] + protocol_id = value['protocol_id'] + blocks_to_ids[block_id] = protocol_id + + ordered_blocks = [] + for block_id in sorted(blocks_to_ids, key=blocks_to_ids.get): + ordered_blocks.append(block_id) + return ordered_blocks diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py index 5f0bc3d9..a380d3d9 100644 --- a/codegen/lib/code/entity.py +++ b/codegen/lib/code/entity.py @@ -111,7 +111,7 @@ use azalea_core::{ direction::Direction, position::{BlockPos, Vec3}, }; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use bevy_ecs::{bundle::Bundle, component::Component}; use derive_more::{Deref, DerefMut}; use thiserror::Error; @@ -428,7 +428,7 @@ impl From for UpdateMetadataError { elif type_name == 'OptionalUnsignedInt': default = f'OptionalUnsignedInt(Some({default}))' if default != 'Empty' else 'OptionalUnsignedInt(None)' elif type_name == 'ItemStack': - default = f'ItemSlot::Present({default})' if default != 'Empty' else 'ItemSlot::Empty' + default = f'ItemStack::Present({default})' if default != 'Empty' else 'ItemStack::Empty' elif type_name == 'BlockState': default = f'{default}' if default != 'Empty' else 'azalea_block::BlockState::AIR' elif type_name == 'OptionalBlockState': diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py index b34d3455..71bc3a70 100755 --- a/codegen/lib/code/packet.py +++ b/codegen/lib/code/packet.py @@ -9,179 +9,80 @@ import re def make_packet_mod_rs_line(packet_id: int, packet_class_name: str): return f' {padded_hex(packet_id)}: {to_snake_case(packet_class_name)}::{to_camel_case(packet_class_name)},' - -def fix_state(state: str): - return {'PLAY': 'game'}.get(state, state.lower()) - - -def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target_packet_direction, target_packet_state): - for packet in burger_packets.values(): - if packet['id'] != target_packet_id: - continue - - direction = packet['direction'].lower() # serverbound or clientbound - state = fix_state(packet['state']) - - if state != target_packet_state or direction != target_packet_direction: - continue - - generated_packet_code = [] - uses = set() - extra_code = [] - - packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet' - - generated_packet_code.append( - f'#[derive(Clone, Debug, McBuf, {packet_derive_name})]') - uses.add(f'azalea_protocol_macros::{packet_derive_name}') - uses.add(f'azalea_buf::McBuf') - - obfuscated_class_name = packet['class'].split('.')[0] - class_name = mappings.get_class( - obfuscated_class_name).split('.')[-1] - if '$' in class_name: - class_name, extra_part = class_name.split('$') - if class_name.endswith('Packet'): - class_name = class_name[:- - len('Packet')] + extra_part + 'Packet' - - generated_packet_code.append( - f'pub struct {to_camel_case(class_name)} {{') - - # call burger_instruction_to_code for each instruction - i = -1 - instructions = packet.get('instructions', []) - while (i + 1) < len(instructions): - i += 1 - - if instructions[i]['operation'] == 'write': - skip = burger_instruction_to_code( - instructions, i, generated_packet_code, mappings, obfuscated_class_name, uses, extra_code) - if skip: - i += skip - else: - generated_packet_code.append(f'// TODO: {instructions[i]}') - - generated_packet_code.append('}') - - if uses: - # empty line before the `use` statements - generated_packet_code.insert(0, '') - for use in uses: - generated_packet_code.insert(0, f'use {use};') - for line in extra_code: - generated_packet_code.append(line) - - print(generated_packet_code) - write_packet_file(state, to_snake_case(class_name), - '\n'.join(generated_packet_code)) - print() - +MOJMAP_TO_AZALEA_STATE_NAME_MAPPING = { + # shorter name, i like it more + 'configuration': 'config', + # in the files mojang calls the directory "game" so we do that too + 'play': 'game' +} +AZALEA_TO_MOJMAP_STATE_NAME_MAPPING = {v: k for k, v in MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.items()} + +def generate_packet(packets_report, packet_name, direction, state): + mojmap_state = AZALEA_TO_MOJMAP_STATE_NAME_MAPPING.get(state, state) + _packet_report = packets_report[mojmap_state][direction]['minecraft:' + packet_name] + + code = [] + uses = set() + + packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet' + + packet_struct_name = to_camel_case(f'{direction}_{packet_name}') + packet_module_name = f'{direction[0]}_{packet_name}' + + code.append(f'use azalea_buf::AzBuf;') + code.append(f'use azalea_protocol_macros::{packet_derive_name};') + code.append('') + + code.append( + f'#[derive(Clone, Debug, AzBuf, {packet_derive_name})]') + code.append( + f'pub struct {packet_struct_name} {{') + code.append(' TODO') + code.append('}') + + print(code) + write_packet_file(state, packet_module_name, '\n'.join(code)) + + # this won't handle writing to the packets/{state}/mod.rs file since we'd need to know the full packet list + +def set_packets(packets_report): + for mojmap_state in packets_report: + state = MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.get(mojmap_state, mojmap_state) mod_rs_dir = get_dir_location( f'../azalea-protocol/src/packets/{state}/mod.rs') - with open(mod_rs_dir, 'r') as f: - mod_rs = f.read().splitlines() - - pub_mod_line = f'pub mod {to_snake_case(class_name)};' - if pub_mod_line not in mod_rs: - mod_rs.insert(0, pub_mod_line) - packet_mod_rs_line = make_packet_mod_rs_line( - packet['id'], class_name) - - in_serverbound = False - in_clientbound = False - for i, line in enumerate(mod_rs): - if line.strip() == 'Serverbound => {': - in_serverbound = True - continue - elif line.strip() == 'Clientbound => {': - in_clientbound = True - continue - elif line.strip() in ('}', '},'): - if (in_serverbound and direction == 'serverbound') or (in_clientbound and direction == 'clientbound'): - mod_rs.insert(i, packet_mod_rs_line) - break - in_serverbound = in_clientbound = False - continue - - if line.strip() == '' or line.strip().startswith('//') or (not in_serverbound and direction == 'serverbound') or (not in_clientbound and direction == 'clientbound'): - continue - - line_packet_id_hex = line.strip().split(':')[0] - assert line_packet_id_hex.startswith('0x') - line_packet_id = int(line_packet_id_hex[2:], 16) - if line_packet_id > packet['id']: - mod_rs.insert(i, packet_mod_rs_line) - break - - with open(mod_rs_dir, 'w') as f: - f.write('\n'.join(mod_rs)) - - -def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: str, state: str): - assert len(packet_ids) == len(packet_class_names) - - # ids are repeated - assert len(packet_ids) == len(set(packet_ids)) - - # sort the packets by id - packet_ids, packet_class_names = [list(x) for x in zip( - *sorted(zip(packet_ids, packet_class_names), key=lambda pair: pair[0]))] # type: ignore - - mod_rs_dir = get_dir_location( - f'../azalea-protocol/src/packets/{state}/mod.rs') - with open(mod_rs_dir, 'r') as f: - mod_rs = f.read().splitlines() - new_mod_rs = [] - - required_modules = [] - - ignore_lines = False - - for line in mod_rs: - if line.strip() == 'Serverbound => {': - new_mod_rs.append(line) - if direction == 'serverbound': - ignore_lines = True - for packet_id, packet_class_name in zip(packet_ids, packet_class_names): - new_mod_rs.append( - make_packet_mod_rs_line(packet_id, packet_class_name) - ) - required_modules.append(packet_class_name) - else: - ignore_lines = False - continue - elif line.strip() == 'Clientbound => {': - new_mod_rs.append(line) - if direction == 'clientbound': - ignore_lines = True - for packet_id, packet_class_name in zip(packet_ids, packet_class_names): - new_mod_rs.append( - make_packet_mod_rs_line(packet_id, packet_class_name) - ) - required_modules.append(packet_class_name) - else: - ignore_lines = False - continue - elif line.strip() in ('}', '},'): - ignore_lines = False - elif line.strip().startswith('pub mod '): - continue - - if not ignore_lines: - new_mod_rs.append(line) - # 0x00: clientbound_status_response_packet::ClientboundStatusResponsePacket, - if line.strip().startswith('0x'): - required_modules.append( - line.strip().split(':')[1].split('::')[0].strip()) - - for i, required_module in enumerate(required_modules): - if required_module not in mod_rs: - new_mod_rs.insert(i, f'pub mod {required_module};') - - with open(mod_rs_dir, 'w') as f: - f.write('\n'.join(new_mod_rs)) + serverbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state]['serverbound']) + clientbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state].get('clientbound', {})) + + code = [] + code.append('// NOTE: This file is generated automatically by codegen/packet.py.') + code.append("// Don't edit it directly!") + code.append('') + code.append('use azalea_protocol_macros::declare_state_packets;') + code.append('') + code.append(f'declare_state_packets!({to_camel_case(state)}Packet,') + code.append(' Clientbound => [') + for packet_name in clientbound_packets: + code.append(f' {packet_name},') + code.append(' ],') + code.append(' Serverbound => [') + for packet_name in serverbound_packets: + code.append(f' {packet_name},') + code.append(' ]') + code.append(');') + code.append('') + + with open(mod_rs_dir, 'w') as f: + f.write('\n'.join(code)) + +def packet_direction_report_to_packet_names(report): + name_to_id = {} + for resource_location, packet in report.items(): + packet_id = packet['protocol_id'] + name_to_id[resource_location.split(':')[-1]] = packet_id + + names_sorted = [name for name in sorted(name_to_id, key=lambda x: name_to_id[x])] + return names_sorted def get_packets(direction: str, state: str): mod_rs_dir = get_dir_location( diff --git a/codegen/lib/code/shapes.py b/codegen/lib/code/shapes.py index 12b333d1..c4964fa6 100755 --- a/codegen/lib/code/shapes.py +++ b/codegen/lib/code/shapes.py @@ -5,11 +5,11 @@ COLLISION_BLOCKS_RS_DIR = get_dir_location( '../azalea-physics/src/collision/blocks.rs') -def generate_block_shapes(blocks_pixlyzer: dict, shapes: dict, aabbs: dict, block_states_report, block_datas_burger, mappings: Mappings): +def generate_block_shapes(blocks_pixlyzer: dict, shapes: dict, aabbs: dict, block_states_report): blocks, shapes = simplify_shapes(blocks_pixlyzer, shapes, aabbs) code = generate_block_shapes_code( - blocks, shapes, block_states_report, block_datas_burger, mappings) + blocks, shapes, block_states_report) with open(COLLISION_BLOCKS_RS_DIR, 'w') as f: f.write(code) @@ -63,7 +63,7 @@ def simplify_shapes(blocks: dict, shapes: dict, aabbs: dict): return new_blocks, new_shapes -def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, block_datas_burger, mappings: Mappings): +def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report): # look at __cache__/generator-mod-*/blockCollisionShapes.json for format of blocks and shapes generated_shape_code = '' @@ -75,7 +75,9 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, empty_shapes = [] full_shapes = [] - block_state_ids_to_shape_ids = [] + # the index into this list is the block state id + shapes_map = [] + for block_id, shape_ids in blocks.items(): if isinstance(shape_ids, int): shape_ids = [shape_ids] @@ -89,17 +91,19 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, elif shape_id == 1 : full_shapes.append(block_state_id) - block_state_ids_to_shape_ids.append((block_state_id, shape_id)) - + while len(shapes_map) <= block_state_id: + # default to shape 1 for missing shapes (full block) + shapes_map.append(1) + shapes_map[block_state_id] = shape_id - generated_map_code = f'static SHAPES_MAP: [&LazyLock; {len(block_state_ids_to_shape_ids)}] = [' + - block_state_ids_to_shape_ids = sorted(block_state_ids_to_shape_ids, key=lambda x: x[0]) + generated_map_code = f'static SHAPES_MAP: [&LazyLock; {len(shapes_map)}] = [' empty_shape_match_code = convert_ints_to_rust_ranges(empty_shapes) block_shape_match_code = convert_ints_to_rust_ranges(full_shapes) - for block_state_id, shape_id in block_state_ids_to_shape_ids: + for block_state_id, shape_id in enumerate(shapes_map): generated_map_code += f'&SHAPE{shape_id},\n' generated_map_code += '];' @@ -109,7 +113,7 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, return f''' //! Autogenerated block collisions for every block -// This file is generated from codegen/lib/code/block_shapes.py. If you want to +// This file is generated from codegen/lib/code/shapes.py. If you want to // modify it, change that file. #![allow(clippy::explicit_auto_deref)] diff --git a/codegen/lib/code/utils.py b/codegen/lib/code/utils.py index 29adc247..1a87b7f6 100755 --- a/codegen/lib/code/utils.py +++ b/codegen/lib/code/utils.py @@ -131,7 +131,7 @@ def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, inst field_type_rs = to_camel_case( enum_name.split('.')[-1].split('$')[-1]) extra_code.append('') - extra_code.append(f'#[derive(McBuf, Clone, Copy, Debug)]') + extra_code.append(f'#[derive(AzBuf, Clone, Copy, Debug)]') extra_code.append(f'pub enum {field_type_rs} {{') for index, variant in enumerate(enum_variants): extra_code.append( @@ -166,8 +166,8 @@ def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, inst return field_type_rs, is_var, uses, extra_code -def write_packet_file(state, packet_name_snake_case, code): - with open(get_dir_location(f'../azalea-protocol/src/packets/{state}/{packet_name_snake_case}.rs'), 'w') as f: +def write_packet_file(state, packet_module_name, code): + with open(get_dir_location(f'../azalea-protocol/src/packets/{state}/{packet_module_name}.rs'), 'w') as f: f.write(code) diff --git a/codegen/lib/code/version.py b/codegen/lib/code/version.py index c2053da3..d4a37232 100755 --- a/codegen/lib/code/version.py +++ b/codegen/lib/code/version.py @@ -31,7 +31,28 @@ def set_version_id(version_id: str) -> None: with open(README_DIR, 'wb') as f: f.write(readme_text.encode()) - + + # update the version in all Cargo.toml files + # version = "0.10.3+mc1.21.1" + for root, _, files in os.walk(get_dir_location('..')): + for file in files: + if file == 'Cargo.toml': + with open(os.path.join(root, file), 'r') as f: + cargo_toml = f.read().splitlines() + for i, line in enumerate(cargo_toml): + if line.strip().startswith('version = '): + replaced = re.sub(r'\+mc[^"]+?"', f'+mc{version_id}"', line) + cargo_toml[i] = replaced + break + else: + # didn't have a version line + continue + if cargo_toml[-1] != '': + # make sure there's always a trailing newline + cargo_toml.append('') + with open(os.path.join(root, file), 'w') as f: + f.write('\n'.join(cargo_toml)) + print('Updated version in README.md and Cargo.toml files') def get_protocol_version() -> str: # azalea-protocol/src/packets/mod.rs @@ -49,7 +70,7 @@ def set_protocol_version(protocol_version: str) -> None: with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'r') as f: mod_rs = f.read().splitlines() for i, line in enumerate(mod_rs): - if line.strip().startswith('pub const PROTOCOL_VERSION'): + if line.strip().startswith('pub const PROTOCOL_VERSION:'): mod_rs[i] = f'pub const PROTOCOL_VERSION: i32 = {protocol_version};' break else: @@ -58,3 +79,16 @@ def set_protocol_version(protocol_version: str) -> None: with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'w') as f: f.write('\n'.join(mod_rs)) +def set_version_name(version_name: str) -> None: + with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'r') as f: + mod_rs = f.read().splitlines() + for i, line in enumerate(mod_rs): + if line.strip().startswith('pub const VERSION_NAME:'): + mod_rs[i] = f'pub const VERSION_NAME: &str = "{version_name}";' + break + else: + raise Exception( + 'Could not find version name in azalea-protocol/src/packets/mod.rs') + + with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'w') as f: + f.write('\n'.join(mod_rs)) diff --git a/codegen/lib/extract.py b/codegen/lib/extract.py index da69b753..4119ad55 100755 --- a/codegen/lib/extract.py +++ b/codegen/lib/extract.py @@ -1,7 +1,7 @@ # Extracting data from the Minecraft jars from typing import TYPE_CHECKING -from lib.download import get_mappings_for_version, get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions +from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions from lib.utils import get_dir_location, to_camel_case, upper_first_letter from zipfile import ZipFile import subprocess @@ -23,17 +23,16 @@ def generate_data_from_server_jar(version_id: str): def get_block_states_report(version_id: str): - generate_data_from_server_jar(version_id) - with open(get_dir_location(f'__cache__/generated-{version_id}/reports/blocks.json'), 'r') as f: - return json.load(f) - - + return get_report(version_id, 'blocks') def get_registries_report(version_id: str): + return get_report(version_id, 'registries') +def get_packets_report(version_id: str): + return get_report(version_id, 'packets') +def get_report(version_id: str, name: str): generate_data_from_server_jar(version_id) - with open(get_dir_location(f'__cache__/generated-{version_id}/reports/registries.json'), 'r') as f: + with open(get_dir_location(f'__cache__/generated-{version_id}/reports/{name}.json'), 'r') as f: return json.load(f) - def get_registry_tags(version_id: str, name: str): generate_data_from_server_jar(version_id) tags_directory = get_dir_location(f'__cache__/generated-{version_id}/data/minecraft/tags/{name}') @@ -50,17 +49,6 @@ def get_registry_tags(version_id: str, name: str): tags[relative_path[:-5]] = json.load(f) return tags - -def get_block_states_burger(version_id: str): - burger_data = get_burger_data_for_version(version_id) - return burger_data[0]['blocks']['block'] - - -def get_ordered_blocks_burger(version_id: str): - burger_data = get_burger_data_for_version(version_id) - return burger_data[0]['blocks']['ordered_blocks'] - - python_command = None diff --git a/codegen/migrate.py b/codegen/migrate.py index 3dcb854a..53d5b588 100755 --- a/codegen/migrate.py +++ b/codegen/migrate.py @@ -1,5 +1,3 @@ -from lib.code.packet import fix_state -from lib.utils import PacketIdentifier, group_packets import lib.code.inventory import lib.code.language import lib.code.registry @@ -31,104 +29,28 @@ new_version_id = sys.argv[1] new_mappings = lib.download.get_mappings_for_version(new_version_id) new_burger_data = lib.extract.get_burger_data_for_version(new_version_id) -old_packet_list = lib.extract.get_packet_list(old_version_id) -new_packet_list = lib.extract.get_packet_list(new_version_id) - - -# old_packets: dict[PacketIdentifier, str] = {} -# old_packets_data: dict[PacketIdentifier, dict] = {} -# new_packets: dict[PacketIdentifier, str] = {} -# new_packets_data: dict[PacketIdentifier, dict] = {} - -# for packet in old_packet_list: -# assert packet['class'].endswith('.class') -# packet_name = old_mappings.get_class(packet['class'][:-6]) -# packet_ident = PacketIdentifier( -# packet['id'], packet['direction'].lower(), fix_state(packet['state'])) -# old_packets[packet_ident] = packet_name -# old_packets_data[packet_ident] = packet -# for packet in new_packet_list: -# assert packet['class'].endswith('.class') -# packet_name = new_mappings.get_class(packet['class'][:-6]) -# packet_ident = PacketIdentifier( -# packet['id'], packet['direction'].lower(), fix_state(packet['state'])) -# new_packets[packet_ident] = packet_name -# new_packets_data[packet_ident] = packet - -# # find removed packets -# removed_packets: list[PacketIdentifier] = [] -# for packet, packet_name in old_packets.items(): -# if packet_name not in new_packets.values(): -# removed_packets.append(packet) -# print('Removed packet:', packet, packet_name) -# for (direction, state), packets in group_packets(removed_packets).items(): -# lib.code.packet.remove_packet_ids(packets, direction, state) - -print() - -# # find packets that changed ids -# changed_packets: dict[PacketIdentifier, int] = {} -# for old_packet, old_packet_name in old_packets.items(): -# for new_packet, new_packet_name in new_packets.items(): -# if old_packet_name == new_packet_name and old_packet.direction == new_packet.direction and old_packet.state == new_packet.state and old_packet.packet_id != new_packet.packet_id: -# changed_packets[old_packet] = new_packet.packet_id -# print('Changed packet id:', old_packet, '->', -# new_packet, f'({new_packet_name})') -# break -# for (direction, state), packets in group_packets(list(changed_packets.keys())).items(): -# id_map: dict[int, int] = {} -# for old_packet_id in packets: -# new_packet_id = changed_packets[PacketIdentifier( -# old_packet_id, direction, state)] -# id_map[old_packet_id] = new_packet_id -# lib.code.packet.change_packet_ids(id_map, direction, state) - - -# print() - -# # find added/changed packets -# added_or_changed_packets: list[PacketIdentifier] = [] -# for new_packet, packet_name in new_packets.items(): -# old_packet = None -# for old_packet_tmp, old_packet_name in old_packets.items(): -# if old_packet_name == packet_name: -# old_packet = old_packet_tmp -# break - -# if packet_name not in old_packets.values(): -# added_or_changed_packets.append(new_packet) -# print('Added packet:', new_packet, packet_name) -# elif old_packet and not lib.code.packet.are_packet_instructions_identical(new_packets_data[new_packet].get('instructions'), old_packets_data[old_packet].get('instructions')): -# added_or_changed_packets.append(new_packet) -# print('Changed packet:', new_packet, packet_name) -# for packet in added_or_changed_packets: -# lib.code.packet.generate_packet( -# new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state) +new_packets_report = lib.extract.get_packets_report(new_version_id) +lib.code.packet.set_packets(new_packets_report) lib.code.version.set_protocol_version( new_burger_data[0]['version']['protocol']) - -# print('Updated protocol!') - - -# old_ordered_blocks = lib.extract.get_ordered_blocks_burger(old_version_id) -# new_ordered_blocks = lib.extract.get_ordered_blocks_burger(new_version_id) -# if old_ordered_blocks != new_ordered_blocks: -# print('Blocks changed, updating...') - -# block_states_burger = lib.extract.get_block_states_burger(new_version_id) -# block_states_report = lib.extract.get_block_states_report(new_version_id) - -# # TODO: pixlyzer is currently broken so uhhhh -# shape_datas = lib.extract.get_pixlyzer_data( -# '1.20.3-pre4', 'shapes') -# pixlyzer_block_datas = lib.extract.get_pixlyzer_data( -# '1.20.3-pre4', 'blocks') - -# lib.code.blocks.generate_blocks( -# block_states_burger, block_states_report, pixlyzer_block_datas, new_ordered_blocks, new_mappings) -# lib.code.shapes.generate_block_shapes( -# pixlyzer_block_datas, shape_datas['shapes'], shape_datas['aabbs'], block_states_report, block_states_burger, new_mappings) +lib.code.version.set_version_name(new_version_id) + +print('Updated protocol!') + +print('Generating blocks and shapes...') +# TODO: pixlyzer is broken so we use old data +new_shape_datas = lib.extract.get_pixlyzer_data( + '1.20.3-pre4', 'shapes') +new_pixlyzer_block_datas = lib.extract.get_pixlyzer_data( + '1.20.3-pre4', 'blocks') +new_block_states_report = lib.extract.get_block_states_report(new_version_id) +new_registries = lib.extract.get_registries_report(new_version_id) +new_ordered_blocks = lib.code.blocks.get_ordered_blocks(new_registries) +lib.code.blocks.generate_blocks( + new_block_states_report, new_pixlyzer_block_datas, new_ordered_blocks) +lib.code.shapes.generate_block_shapes( + new_pixlyzer_block_datas, new_shape_datas['shapes'], new_shape_datas['aabbs'], new_block_states_report) print('Getting en_us.json...') language = lib.extract.get_en_us_lang(new_version_id) @@ -139,13 +61,12 @@ import genregistries genregistries.generate(new_version_id) # print('Generating entity metadata...') -# burger_entities_data = new_burger_data[0]['entities'] -# lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings) +burger_entities_data = new_burger_data[0]['entities'] +lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings) print('Finishing touches, setting version in README and formatting code...') lib.code.version.set_version_id(new_version_id) - lib.code.utils.fmt() print('Done!') diff --git a/codegen/newpacket.py b/codegen/newpacket.py index d8edcde1..97408e05 100755 --- a/codegen/newpacket.py +++ b/codegen/newpacket.py @@ -5,18 +5,20 @@ import lib.download import lib.extract import sys -version_id = lib.code.version.get_version_id() +def generate(): + version_id = lib.code.version.get_version_id() -mappings = lib.download.get_mappings_for_version(version_id) -burger_data = lib.extract.get_burger_data_for_version(version_id) + packets_report = lib.extract.get_packets_report(version_id) -burger_packets_data = burger_data[0]['packets']['packet'] -packet_id, direction, state = int(sys.argv[1], 0), sys.argv[2], sys.argv[3] -print( - f'Generating code for packet id: {packet_id} with direction {direction} and state {state}') -lib.code.packet.generate_packet(burger_packets_data, mappings, - packet_id, direction, state) + packet_id, direction, state = sys.argv[1], sys.argv[2], sys.argv[3] + print( + f'Generating code for packet id: {packet_id} with direction {direction} and state {state}') + lib.code.packet.generate_packet(packets_report, packet_id, direction, state) + lib.code.packet.set_packets(packets_report) -lib.code.utils.fmt() + lib.code.utils.fmt() -print('Done!') + print('Done!') + +if __name__ == '__main__': + generate() -- cgit v1.2.3