From 51e273df3575b0a19fc0a11e5a39d5367948d6e8 Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 2 Feb 2024 04:30:29 -0800 Subject: [PATCH 01/11] Move everything to `old` directory to make things easier while the rewrite is taking place. --- .../.devcontainer}/devcontainer.json | 0 {.github => old/.github}/FUNDING.yml | 0 .../.github}/ISSUE_TEMPLATE/bug_report.md | 0 {.github => old/.github}/ISSUE_TEMPLATE/config.yml | 0 .../.github}/ISSUE_TEMPLATE/feature_request.md | 0 {.github => old/.github}/dependabot.yml | 0 {.github => old/.github}/pull_request_template.md | 0 .../.github}/workflows/ci-pr-comments.yml | 0 {.github => old/.github}/workflows/ci.yml | 0 {.github => old/.github}/workflows/website.yml | 0 .gitignore => old/.gitignore | 0 CODE_OF_CONDUCT.md => old/CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md => old/CONTRIBUTING.md | 0 Cargo.toml => old/Cargo.toml | 0 LICENSE.txt => old/LICENSE.txt | 0 README.md => old/README.md | 0 {assets => old/assets}/depgraph.svg | 0 {assets => old/assets}/example_pack.zip | Bin {assets => old/assets}/logo-256x256.png | Bin {assets => old/assets}/logo-64x64.png | Bin {assets => old/assets}/logo-full.svg | 0 {assets => old/assets}/logo.svg | 0 {assets => old/assets}/many-players.png | Bin {assets => old/assets}/packet-inspector.png | Bin {benches => old/benches}/anvil.rs | 0 {benches => old/benches}/block.rs | 0 {benches => old/benches}/decode_array.rs | 0 {benches => old/benches}/idle.rs | 0 {benches => old/benches}/main.rs | 0 {benches => old/benches}/many_players.rs | 0 {benches => old/benches}/packet.rs | 0 {benches => old/benches}/var_int.rs | 0 {benches => old/benches}/var_long.rs | 0 {crates => old/crates}/README.md | 0 {crates => old/crates}/java_string/Cargo.toml | 0 {crates => old/crates}/java_string/README.md | 0 {crates => old/crates}/java_string/src/cesu8.rs | 0 {crates => old/crates}/java_string/src/char.rs | 0 {crates => old/crates}/java_string/src/error.rs | 0 {crates => old/crates}/java_string/src/iter.rs | 0 {crates => old/crates}/java_string/src/lib.rs | 0 {crates => old/crates}/java_string/src/owned.rs | 0 {crates => old/crates}/java_string/src/pattern.rs | 0 {crates => old/crates}/java_string/src/serde.rs | 0 {crates => old/crates}/java_string/src/slice.rs | 0 .../crates}/java_string/src/validations.rs | 0 .../crates}/valence_advancement/Cargo.toml | 0 .../crates}/valence_advancement/README.md | 0 .../crates}/valence_advancement/src/event.rs | 0 .../crates}/valence_advancement/src/lib.rs | 0 {crates => old/crates}/valence_anvil/Cargo.toml | 0 {crates => old/crates}/valence_anvil/README.md | 0 {crates => old/crates}/valence_anvil/src/bevy.rs | 0 {crates => old/crates}/valence_anvil/src/lib.rs | 0 {crates => old/crates}/valence_anvil/src/parsing.rs | 0 {crates => old/crates}/valence_boss_bar/Cargo.toml | 0 {crates => old/crates}/valence_boss_bar/README.md | 0 .../crates}/valence_boss_bar/src/components.rs | 0 {crates => old/crates}/valence_boss_bar/src/lib.rs | 0 .../crates}/valence_build_utils/Cargo.toml | 0 .../crates}/valence_build_utils/README.md | 0 .../crates}/valence_build_utils/src/lib.rs | 0 {crates => old/crates}/valence_command/Cargo.toml | 0 {crates => old/crates}/valence_command/README.md | 0 {crates => old/crates}/valence_command/src/graph.rs | 0 .../crates}/valence_command/src/handler.rs | 0 {crates => old/crates}/valence_command/src/lib.rs | 0 .../crates}/valence_command/src/manager.rs | 0 .../crates}/valence_command/src/modifier_value.rs | 0 .../crates}/valence_command/src/parsers.rs | 0 .../crates}/valence_command/src/parsers/angle.rs | 0 .../valence_command/src/parsers/block_pos.rs | 0 .../crates}/valence_command/src/parsers/bool.rs | 0 .../crates}/valence_command/src/parsers/color.rs | 0 .../valence_command/src/parsers/column_pos.rs | 0 .../valence_command/src/parsers/entity_anchor.rs | 0 .../valence_command/src/parsers/entity_selector.rs | 0 .../crates}/valence_command/src/parsers/gamemode.rs | 0 .../valence_command/src/parsers/inventory_slot.rs | 0 .../crates}/valence_command/src/parsers/numbers.rs | 0 .../crates}/valence_command/src/parsers/rotation.rs | 0 .../valence_command/src/parsers/score_holder.rs | 0 .../crates}/valence_command/src/parsers/strings.rs | 0 .../crates}/valence_command/src/parsers/swizzle.rs | 0 .../crates}/valence_command/src/parsers/time.rs | 0 .../crates}/valence_command/src/parsers/vec2.rs | 0 .../crates}/valence_command/src/parsers/vec3.rs | 0 .../crates}/valence_command/src/scopes.rs | 0 .../crates}/valence_command_macros/Cargo.toml | 0 .../crates}/valence_command_macros/README.md | 0 .../crates}/valence_command_macros/src/lib.rs | 0 {crates => old/crates}/valence_entity/Cargo.toml | 0 {crates => old/crates}/valence_entity/README.md | 0 {crates => old/crates}/valence_entity/build.rs | 0 .../crates}/valence_entity/extracted/entities.json | 0 .../crates}/valence_entity/extracted/misc.json | 0 .../valence_entity/src/active_status_effects.rs | 0 .../crates}/valence_entity/src/attributes.rs | 0 {crates => old/crates}/valence_entity/src/flags.rs | 0 {crates => old/crates}/valence_entity/src/hitbox.rs | 0 {crates => old/crates}/valence_entity/src/lib.rs | 0 .../crates}/valence_entity/src/manager.rs | 0 {crates => old/crates}/valence_entity/src/query.rs | 0 .../crates}/valence_entity/src/tracked_data.rs | 0 {crates => old/crates}/valence_generated/Cargo.toml | 0 {crates => old/crates}/valence_generated/README.md | 0 .../crates}/valence_generated/build/attributes.rs | 0 .../crates}/valence_generated/build/block.rs | 0 .../crates}/valence_generated/build/chunk_view.rs | 0 .../crates}/valence_generated/build/item.rs | 0 .../crates}/valence_generated/build/main.rs | 0 .../crates}/valence_generated/build/packet_id.rs | 0 .../crates}/valence_generated/build/sound.rs | 0 .../valence_generated/build/status_effects.rs | 0 .../valence_generated/extracted/attributes.json | 0 .../crates}/valence_generated/extracted/blocks.json | 0 .../valence_generated/extracted/effects.json | 0 .../crates}/valence_generated/extracted/items.json | 0 .../valence_generated/extracted/packets.json | 0 .../crates}/valence_generated/extracted/sounds.json | 0 .../crates}/valence_generated/src/block.rs | 0 {crates => old/crates}/valence_generated/src/lib.rs | 0 {crates => old/crates}/valence_ident/Cargo.toml | 0 {crates => old/crates}/valence_ident/README.md | 0 {crates => old/crates}/valence_ident/src/lib.rs | 0 .../crates}/valence_ident_macros/Cargo.toml | 0 .../crates}/valence_ident_macros/README.md | 0 .../crates}/valence_ident_macros/src/lib.rs | 0 {crates => old/crates}/valence_inventory/Cargo.toml | 0 {crates => old/crates}/valence_inventory/README.md | 0 {crates => old/crates}/valence_inventory/src/lib.rs | 0 .../valence_inventory/src/player_inventory.rs | 0 .../crates}/valence_inventory/src/validate.rs | 0 {crates => old/crates}/valence_lang/Cargo.toml | 0 {crates => old/crates}/valence_lang/README.md | 0 {crates => old/crates}/valence_lang/build.rs | 0 .../valence_lang/extracted/translation_keys.json | 0 {crates => old/crates}/valence_lang/src/lib.rs | 0 {crates => old/crates}/valence_math/Cargo.toml | 0 {crates => old/crates}/valence_math/README.md | 0 {crates => old/crates}/valence_math/src/aabb.rs | 0 {crates => old/crates}/valence_math/src/lib.rs | 0 {crates => old/crates}/valence_nbt/Cargo.toml | 0 {crates => old/crates}/valence_nbt/README.md | 0 {crates => old/crates}/valence_nbt/src/binary.rs | 0 .../crates}/valence_nbt/src/binary/decode.rs | 0 .../crates}/valence_nbt/src/binary/encode.rs | 0 .../crates}/valence_nbt/src/binary/error.rs | 0 .../crates}/valence_nbt/src/binary/modified_utf8.rs | 0 .../crates}/valence_nbt/src/binary/tests.rs | 0 {crates => old/crates}/valence_nbt/src/compound.rs | 0 {crates => old/crates}/valence_nbt/src/conv.rs | 0 {crates => old/crates}/valence_nbt/src/lib.rs | 0 {crates => old/crates}/valence_nbt/src/list.rs | 0 {crates => old/crates}/valence_nbt/src/serde.rs | 0 {crates => old/crates}/valence_nbt/src/serde/de.rs | 0 {crates => old/crates}/valence_nbt/src/serde/ser.rs | 0 .../crates}/valence_nbt/src/serde/tests.rs | 0 {crates => old/crates}/valence_nbt/src/snbt.rs | 0 {crates => old/crates}/valence_nbt/src/tag.rs | 0 {crates => old/crates}/valence_nbt/src/value.rs | 0 {crates => old/crates}/valence_network/Cargo.toml | 0 {crates => old/crates}/valence_network/README.md | 0 .../crates}/valence_network/src/byte_channel.rs | 0 .../crates}/valence_network/src/connect.rs | 0 .../crates}/valence_network/src/legacy_ping.rs | 0 {crates => old/crates}/valence_network/src/lib.rs | 0 .../crates}/valence_network/src/packet_io.rs | 0 .../crates}/valence_player_list/Cargo.toml | 0 .../crates}/valence_player_list/README.md | 0 .../crates}/valence_player_list/src/lib.rs | 0 {crates => old/crates}/valence_protocol/Cargo.toml | 0 {crates => old/crates}/valence_protocol/README.md | 0 .../crates}/valence_protocol/src/array.rs | 0 .../crates}/valence_protocol/src/biome_pos.rs | 0 .../crates}/valence_protocol/src/bit_set.rs | 0 .../crates}/valence_protocol/src/block_pos.rs | 0 .../crates}/valence_protocol/src/bounded.rs | 0 .../crates}/valence_protocol/src/byte_angle.rs | 0 .../crates}/valence_protocol/src/chunk_pos.rs | 0 .../valence_protocol/src/chunk_section_pos.rs | 0 .../crates}/valence_protocol/src/decode.rs | 0 .../crates}/valence_protocol/src/difficulty.rs | 0 .../crates}/valence_protocol/src/direction.rs | 0 .../crates}/valence_protocol/src/encode.rs | 0 .../crates}/valence_protocol/src/game_mode.rs | 0 .../crates}/valence_protocol/src/global_pos.rs | 0 {crates => old/crates}/valence_protocol/src/hand.rs | 0 .../crates}/valence_protocol/src/impls.rs | 0 .../crates}/valence_protocol/src/impls/map.rs | 0 .../crates}/valence_protocol/src/impls/math.rs | 0 .../crates}/valence_protocol/src/impls/other.rs | 0 .../crates}/valence_protocol/src/impls/pointer.rs | 0 .../crates}/valence_protocol/src/impls/primitive.rs | 0 .../crates}/valence_protocol/src/impls/sequence.rs | 0 .../crates}/valence_protocol/src/impls/string.rs | 0 .../crates}/valence_protocol/src/impls/tuple.rs | 0 {crates => old/crates}/valence_protocol/src/item.rs | 0 {crates => old/crates}/valence_protocol/src/lib.rs | 0 .../crates}/valence_protocol/src/packets.rs | 0 .../src/packets/handshaking/handshake_c2s.rs | 0 .../src/packets/login/login_compression_s2c.rs | 0 .../src/packets/login/login_disconnect_s2c.rs | 0 .../src/packets/login/login_hello_c2s.rs | 0 .../src/packets/login/login_hello_s2c.rs | 0 .../src/packets/login/login_key_c2s.rs | 0 .../src/packets/login/login_query_request_s2c.rs | 0 .../src/packets/login/login_query_response_c2s.rs | 0 .../src/packets/login/login_success_s2c.rs | 0 .../src/packets/play/advancement_tab_c2s.rs | 0 .../src/packets/play/advancement_update_s2c.rs | 0 .../src/packets/play/block_breaking_progress_s2c.rs | 0 .../src/packets/play/block_entity_update_s2c.rs | 0 .../src/packets/play/block_event_s2c.rs | 0 .../src/packets/play/block_update_s2c.rs | 0 .../src/packets/play/boat_paddle_state_c2s.rs | 0 .../src/packets/play/book_update_c2s.rs | 0 .../src/packets/play/boss_bar_s2c.rs | 0 .../src/packets/play/bundle_splitter_s2c.rs | 0 .../src/packets/play/button_click_c2s.rs | 0 .../src/packets/play/chat_message_c2s.rs | 0 .../src/packets/play/chat_message_s2c.rs | 0 .../src/packets/play/chat_suggestions_s2c.rs | 0 .../src/packets/play/chunk_biome_data_s2c.rs | 0 .../src/packets/play/chunk_data_s2c.rs | 0 .../src/packets/play/chunk_delta_update_s2c.rs | 0 .../src/packets/play/chunk_load_distance_s2c.rs | 0 .../play/chunk_render_distance_center_s2c.rs | 0 .../src/packets/play/clear_title_s2c.rs | 0 .../src/packets/play/click_slot_c2s.rs | 0 .../src/packets/play/client_command_c2s.rs | 0 .../src/packets/play/client_settings_c2s.rs | 0 .../src/packets/play/client_status_c2s.rs | 0 .../src/packets/play/close_handled_screen_c2s.rs | 0 .../src/packets/play/close_screen_s2c.rs | 0 .../src/packets/play/command_execution_c2s.rs | 0 .../src/packets/play/command_suggestions_s2c.rs | 0 .../src/packets/play/command_tree_s2c.rs | 0 .../src/packets/play/cooldown_update_s2c.rs | 0 .../src/packets/play/craft_failed_response_s2c.rs | 0 .../src/packets/play/craft_request_c2s.rs | 0 .../packets/play/creative_inventory_action_c2s.rs | 0 .../src/packets/play/custom_payload_c2s.rs | 0 .../src/packets/play/custom_payload_s2c.rs | 0 .../src/packets/play/damage_tilt_s2c.rs | 0 .../src/packets/play/death_message_s2c.rs | 0 .../src/packets/play/difficulty_s2c.rs | 0 .../src/packets/play/disconnect_s2c.rs | 0 .../src/packets/play/end_combat_s2c.rs | 0 .../src/packets/play/enter_combat_s2c.rs | 0 .../src/packets/play/entities_destroy_s2c.rs | 0 .../src/packets/play/entity_animation_s2c.rs | 0 .../src/packets/play/entity_attach_s2c.rs | 0 .../src/packets/play/entity_attributes_s2c.rs | 0 .../src/packets/play/entity_damage_s2c.rs | 0 .../src/packets/play/entity_equipment_update_s2c.rs | 0 .../src/packets/play/entity_passengers_set_s2c.rs | 0 .../src/packets/play/entity_position_s2c.rs | 0 .../src/packets/play/entity_set_head_yaw_s2c.rs | 0 .../src/packets/play/entity_spawn_s2c.rs | 0 .../src/packets/play/entity_status_effect_s2c.rs | 0 .../src/packets/play/entity_status_s2c.rs | 0 .../src/packets/play/entity_tracker_update_s2c.rs | 0 .../src/packets/play/entity_velocity_update_s2c.rs | 0 .../src/packets/play/experience_bar_update_s2c.rs | 0 .../src/packets/play/experience_orb_spawn_s2c.rs | 0 .../src/packets/play/explosion_s2c.rs | 0 .../src/packets/play/features_s2c.rs | 0 .../valence_protocol/src/packets/play/full_c2s.rs | 0 .../src/packets/play/game_join_s2c.rs | 0 .../src/packets/play/game_message_s2c.rs | 0 .../src/packets/play/game_state_change_s2c.rs | 0 .../src/packets/play/hand_swing_c2s.rs | 0 .../src/packets/play/health_update_s2c.rs | 0 .../src/packets/play/inventory_s2c.rs | 0 .../src/packets/play/item_pickup_animation_s2c.rs | 0 .../src/packets/play/jigsaw_generating_c2s.rs | 0 .../src/packets/play/keep_alive_c2s.rs | 0 .../src/packets/play/keep_alive_s2c.rs | 0 .../src/packets/play/light_update_s2c.rs | 0 .../src/packets/play/look_and_on_ground_c2s.rs | 0 .../src/packets/play/look_at_s2c.rs | 0 .../src/packets/play/map_update_s2c.rs | 0 .../src/packets/play/message_acknowledgment_c2s.rs | 0 .../src/packets/play/move_relative_s2c.rs | 0 .../src/packets/play/nbt_query_response_s2c.rs | 0 .../src/packets/play/on_ground_only_c2s.rs | 0 .../src/packets/play/open_horse_screen_s2c.rs | 0 .../src/packets/play/open_screen_s2c.rs | 0 .../src/packets/play/open_written_book_s2c.rs | 0 .../src/packets/play/overlay_message_s2c.rs | 0 .../src/packets/play/particle_s2c.rs | 0 .../src/packets/play/pick_from_inventory_c2s.rs | 0 .../src/packets/play/play_ping_s2c.rs | 0 .../src/packets/play/play_pong_c2s.rs | 0 .../src/packets/play/play_sound_from_entity_s2c.rs | 0 .../src/packets/play/play_sound_s2c.rs | 0 .../src/packets/play/player_abilities_s2c.rs | 0 .../src/packets/play/player_action_c2s.rs | 0 .../src/packets/play/player_action_response_s2c.rs | 0 .../src/packets/play/player_input_c2s.rs | 0 .../src/packets/play/player_interact_block_c2s.rs | 0 .../src/packets/play/player_interact_entity_c2s.rs | 0 .../src/packets/play/player_interact_item_c2s.rs | 0 .../src/packets/play/player_list_header_s2c.rs | 0 .../src/packets/play/player_list_s2c.rs | 0 .../src/packets/play/player_position_look_s2c.rs | 0 .../src/packets/play/player_remove_s2c.rs | 0 .../src/packets/play/player_respawn_s2c.rs | 0 .../src/packets/play/player_session_c2s.rs | 0 .../src/packets/play/player_spawn_position_s2c.rs | 0 .../src/packets/play/player_spawn_s2c.rs | 0 .../src/packets/play/position_and_on_ground_c2s.rs | 0 .../packets/play/profileless_chat_message_s2c.rs | 0 .../src/packets/play/query_block_nbt_c2s.rs | 0 .../src/packets/play/query_entity_nbt_c2s.rs | 0 .../src/packets/play/recipe_book_data_c2s.rs | 0 .../src/packets/play/recipe_category_options_c2s.rs | 0 .../packets/play/remove_entity_status_effect_s2c.rs | 0 .../src/packets/play/remove_message_s2c.rs | 0 .../src/packets/play/rename_item_c2s.rs | 0 .../packets/play/request_command_completions_c2s.rs | 0 .../src/packets/play/resource_pack_send_s2c.rs | 0 .../src/packets/play/resource_pack_status_c2s.rs | 0 .../packets/play/rotate_and_move_relative_s2c.rs | 0 .../valence_protocol/src/packets/play/rotate_s2c.rs | 0 .../src/packets/play/scoreboard_display_s2c.rs | 0 .../packets/play/scoreboard_objective_update_s2c.rs | 0 .../packets/play/scoreboard_player_update_s2c.rs | 0 .../play/screen_handler_property_update_s2c.rs | 0 .../packets/play/screen_handler_slot_update_s2c.rs | 0 .../src/packets/play/select_advancement_tab_s2c.rs | 0 .../src/packets/play/select_merchant_trade_c2s.rs | 0 .../src/packets/play/server_metadata_s2c.rs | 0 .../src/packets/play/set_camera_entity_s2c.rs | 0 .../src/packets/play/set_trade_offers_s2c.rs | 0 .../src/packets/play/sign_editor_open_s2c.rs | 0 .../src/packets/play/simulation_distance_s2c.rs | 0 .../src/packets/play/spectator_teleport_c2s.rs | 0 .../src/packets/play/statistics_s2c.rs | 0 .../src/packets/play/stop_sound_s2c.rs | 0 .../src/packets/play/subtitle_s2c.rs | 0 .../src/packets/play/synchronize_recipes_s2c.rs | 0 .../src/packets/play/synchronize_tags_s2c.rs | 0 .../valence_protocol/src/packets/play/team_s2c.rs | 0 .../src/packets/play/teleport_confirm_c2s.rs | 0 .../src/packets/play/title_fade_s2c.rs | 0 .../valence_protocol/src/packets/play/title_s2c.rs | 0 .../src/packets/play/unload_chunk_s2c.rs | 0 .../src/packets/play/unlock_recipes_s2c.rs | 0 .../src/packets/play/update_beacon_c2s.rs | 0 .../src/packets/play/update_command_block_c2s.rs | 0 .../play/update_command_block_minecart_c2s.rs | 0 .../src/packets/play/update_difficulty_c2s.rs | 0 .../src/packets/play/update_difficulty_lock_c2s.rs | 0 .../src/packets/play/update_jigsaw_c2s.rs | 0 .../src/packets/play/update_player_abilities_c2s.rs | 0 .../src/packets/play/update_selected_slot_c2s.rs | 0 .../src/packets/play/update_selected_slot_s2c.rs | 0 .../src/packets/play/update_sign_c2s.rs | 0 .../src/packets/play/update_structure_block_c2s.rs | 0 .../src/packets/play/vehicle_move_c2s.rs | 0 .../src/packets/play/vehicle_move_s2c.rs | 0 .../packets/play/world_border_center_changed_s2c.rs | 0 .../src/packets/play/world_border_initialize_s2c.rs | 0 .../play/world_border_interpolate_size_s2c.rs | 0 .../packets/play/world_border_size_changed_s2c.rs | 0 .../play/world_border_warning_blocks_changed_s2c.rs | 0 .../play/world_border_warning_time_changed_s2c.rs | 0 .../src/packets/play/world_event_s2c.rs | 0 .../src/packets/play/world_time_update_s2c.rs | 0 .../crates}/valence_protocol/src/packets/status.rs | 0 .../src/packets/status/query_ping_c2s.rs | 0 .../src/packets/status/query_pong_s2c.rs | 0 .../src/packets/status/query_request_c2s.rs | 0 .../src/packets/status/query_response_s2c.rs | 0 .../crates}/valence_protocol/src/profile.rs | 0 {crates => old/crates}/valence_protocol/src/raw.rs | 0 .../crates}/valence_protocol/src/sound.rs | 0 .../crates}/valence_protocol/src/var_int.rs | 0 .../crates}/valence_protocol/src/var_long.rs | 0 .../crates}/valence_protocol/src/velocity.rs | 0 .../crates}/valence_protocol_macros/Cargo.toml | 0 .../crates}/valence_protocol_macros/README.md | 0 .../crates}/valence_protocol_macros/src/decode.rs | 0 .../crates}/valence_protocol_macros/src/encode.rs | 0 .../crates}/valence_protocol_macros/src/lib.rs | 0 .../crates}/valence_protocol_macros/src/packet.rs | 0 {crates => old/crates}/valence_registry/Cargo.toml | 0 {crates => old/crates}/valence_registry/README.md | 0 .../valence_registry/extracted/registry_codec.dat | Bin .../crates}/valence_registry/extracted/tags.json | 0 .../crates}/valence_registry/src/biome.rs | 0 .../crates}/valence_registry/src/codec.rs | 0 .../crates}/valence_registry/src/dimension_type.rs | 0 {crates => old/crates}/valence_registry/src/lib.rs | 0 {crates => old/crates}/valence_registry/src/tags.rs | 0 .../crates}/valence_scoreboard/Cargo.toml | 0 {crates => old/crates}/valence_scoreboard/README.md | 0 .../crates}/valence_scoreboard/src/components.rs | 0 .../crates}/valence_scoreboard/src/lib.rs | 0 {crates => old/crates}/valence_server/Cargo.toml | 0 {crates => old/crates}/valence_server/README.md | 0 .../crates}/valence_server/src/abilities.rs | 0 {crates => old/crates}/valence_server/src/action.rs | 0 {crates => old/crates}/valence_server/src/brand.rs | 0 .../crates}/valence_server/src/chunk_view.rs | 0 {crates => old/crates}/valence_server/src/client.rs | 0 .../crates}/valence_server/src/client_command.rs | 0 .../crates}/valence_server/src/client_settings.rs | 0 .../crates}/valence_server/src/custom_payload.rs | 0 .../crates}/valence_server/src/event_loop.rs | 0 .../crates}/valence_server/src/hand_swing.rs | 0 .../crates}/valence_server/src/interact_block.rs | 0 .../crates}/valence_server/src/interact_entity.rs | 0 .../crates}/valence_server/src/interact_item.rs | 0 .../crates}/valence_server/src/keepalive.rs | 0 {crates => old/crates}/valence_server/src/layer.rs | 0 .../crates}/valence_server/src/layer/bvh.rs | 0 .../crates}/valence_server/src/layer/chunk.rs | 0 .../crates}/valence_server/src/layer/chunk/chunk.rs | 0 .../valence_server/src/layer/chunk/loaded.rs | 0 .../src/layer/chunk/paletted_container.rs | 0 .../valence_server/src/layer/chunk/unloaded.rs | 0 .../crates}/valence_server/src/layer/entity.rs | 0 .../crates}/valence_server/src/layer/message.rs | 0 {crates => old/crates}/valence_server/src/lib.rs | 0 .../crates}/valence_server/src/message.rs | 0 .../crates}/valence_server/src/movement.rs | 0 .../crates}/valence_server/src/op_level.rs | 0 .../crates}/valence_server/src/resource_pack.rs | 0 {crates => old/crates}/valence_server/src/spawn.rs | 0 {crates => old/crates}/valence_server/src/status.rs | 0 .../crates}/valence_server/src/status_effect.rs | 0 .../crates}/valence_server/src/teleport.rs | 0 {crates => old/crates}/valence_server/src/title.rs | 0 .../crates}/valence_server_common/Cargo.toml | 0 .../crates}/valence_server_common/README.md | 0 .../crates}/valence_server_common/src/despawn.rs | 0 .../crates}/valence_server_common/src/lib.rs | 0 .../crates}/valence_server_common/src/uuid.rs | 0 {crates => old/crates}/valence_spatial/Cargo.toml | 0 {crates => old/crates}/valence_spatial/README.md | 0 {crates => old/crates}/valence_spatial/src/bvh.rs | 0 {crates => old/crates}/valence_spatial/src/lib.rs | 0 {crates => old/crates}/valence_text/Cargo.toml | 0 {crates => old/crates}/valence_text/README.md | 0 {crates => old/crates}/valence_text/src/color.rs | 0 .../crates}/valence_text/src/into_text.rs | 0 {crates => old/crates}/valence_text/src/lib.rs | 0 {crates => old/crates}/valence_text/src/tests.rs | 0 {crates => old/crates}/valence_weather/Cargo.toml | 0 {crates => old/crates}/valence_weather/README.md | 0 {crates => old/crates}/valence_weather/src/lib.rs | 0 .../crates}/valence_weather/src/packet.rs | 0 .../crates}/valence_world_border/Cargo.toml | 0 .../crates}/valence_world_border/README.md | 0 .../crates}/valence_world_border/src/lib.rs | 0 {examples => old/examples}/advancement.rs | 0 {examples => old/examples}/anvil_loading.rs | 0 {examples => old/examples}/bench_players.rs | 0 {examples => old/examples}/biomes.rs | 0 {examples => old/examples}/block_entities.rs | 0 {examples => old/examples}/boss_bar.rs | 0 {examples => old/examples}/building.rs | 0 {examples => old/examples}/chest.rs | 0 {examples => old/examples}/combat.rs | 0 {examples => old/examples}/command.rs | 0 {examples => old/examples}/cow_sphere.rs | 0 {examples => old/examples}/ctf.rs | 0 {examples => old/examples}/custom_npc.rs | 0 {examples => old/examples}/death.rs | 0 {examples => old/examples}/entity_hitbox.rs | 0 {examples => old/examples}/game_of_life.rs | 0 {examples => old/examples}/parkour.rs | 0 {examples => old/examples}/particles.rs | 0 {examples => old/examples}/player_list.rs | 0 {examples => old/examples}/potions.rs | 0 {examples => old/examples}/resource_pack.rs | 0 {examples => old/examples}/server_list_ping.rs | 0 {examples => old/examples}/terrain.rs | 0 {examples => old/examples}/text.rs | 0 {examples => old/examples}/weather.rs | 0 {examples => old/examples}/world_border.rs | 0 {extractor => old/extractor}/README.md | 0 {extractor => old/extractor}/build.gradle | 0 .../extractor}/copy_extractor_output.sh | 0 {extractor => old/extractor}/gradle.properties | 0 .../extractor}/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {extractor => old/extractor}/gradlew | 0 {extractor => old/extractor}/gradlew.bat | 0 {extractor => old/extractor}/settings.gradle | 0 .../java/rs/valence/extractor/ClassComparator.java | 0 .../rs/valence/extractor/DummyPlayerEntity.java | 0 .../main/java/rs/valence/extractor/DummyWorld.java | 0 .../src/main/java/rs/valence/extractor/Main.java | 0 .../rs/valence/extractor/RegistryKeyComparator.java | 0 .../java/rs/valence/extractor/ValenceUtils.java | 0 .../rs/valence/extractor/extractors/Attributes.java | 0 .../rs/valence/extractor/extractors/Biomes.java | 0 .../rs/valence/extractor/extractors/Blocks.java | 0 .../java/rs/valence/extractor/extractors/Codec.java | 0 .../rs/valence/extractor/extractors/Effects.java | 0 .../rs/valence/extractor/extractors/Enchants.java | 0 .../rs/valence/extractor/extractors/Entities.java | 0 .../java/rs/valence/extractor/extractors/Items.java | 0 .../java/rs/valence/extractor/extractors/Misc.java | 0 .../rs/valence/extractor/extractors/Packets.java | 0 .../rs/valence/extractor/extractors/Sounds.java | 0 .../java/rs/valence/extractor/extractors/Tags.java | 0 .../extractor/extractors/TranslationKeys.java | 0 .../rs/valence/extractor/mixin/ExposeWallBlock.java | 0 .../src/main/resources/extractor.mixins.json | 0 .../extractor}/src/main/resources/fabric.mod.json | 0 rustfmt.toml => old/rustfmt.toml | 0 {src => old/src}/lib.rs | 0 {src => old/src}/testing.rs | 0 {src => old/src}/tests.rs | 0 {src => old/src}/tests/boss_bar.rs | 0 {src => old/src}/tests/client.rs | 0 {src => old/src}/tests/example.rs | 0 {src => old/src}/tests/hunger.rs | 0 {src => old/src}/tests/inventory.rs | 0 {src => old/src}/tests/layer.rs | 0 {src => old/src}/tests/player_list.rs | 0 {src => old/src}/tests/potions.rs | 0 {src => old/src}/tests/scoreboard.rs | 0 {src => old/src}/tests/weather.rs | 0 {src => old/src}/tests/world_border.rs | 0 {tools => old/tools}/dump_schedule/Cargo.toml | 0 {tools => old/tools}/dump_schedule/README.md | 0 {tools => old/tools}/dump_schedule/src/main.rs | 0 {tools => old/tools}/packet_inspector/Cargo.toml | 0 {tools => old/tools}/packet_inspector/README.md | 0 {tools => old/tools}/packet_inspector/build.rs | 0 .../tools}/packet_inspector/extracted/packets.json | 0 {tools => old/tools}/packet_inspector/src/app.rs | 0 .../tools}/packet_inspector/src/app/connection.rs | 0 .../tools}/packet_inspector/src/app/filter.rs | 0 .../tools}/packet_inspector/src/app/hex_viewer.rs | 0 .../tools}/packet_inspector/src/app/packet_list.rs | 0 .../tools}/packet_inspector/src/app/text_viewer.rs | 0 {tools => old/tools}/packet_inspector/src/lib.rs | 0 {tools => old/tools}/packet_inspector/src/main.rs | 0 .../tools}/packet_inspector/src/main_cli.rs | 0 .../tools}/packet_inspector/src/packet_io.rs | 0 .../tools}/packet_inspector/src/packet_registry.rs | 0 .../tools}/packet_inspector/src/shared_state.rs | 0 .../tools}/packet_inspector/src/tri_checkbox.rs | 0 {tools => old/tools}/playground/Cargo.toml | 0 {tools => old/tools}/playground/README.md | 0 {tools => old/tools}/playground/build.rs | 0 {tools => old/tools}/playground/src/.gitignore | 0 {tools => old/tools}/playground/src/extras.rs | 0 {tools => old/tools}/playground/src/main.rs | 0 .../tools}/playground/src/playground.template.rs | 0 {tools => old/tools}/stresser/Cargo.toml | 0 {tools => old/tools}/stresser/README.md | 0 {tools => old/tools}/stresser/src/args.rs | 0 {tools => old/tools}/stresser/src/main.rs | 0 {tools => old/tools}/stresser/src/stresser.rs | 0 typos.toml => old/typos.toml | 0 {website => old/website}/.gitignore | 0 {website => old/website}/README.md | 0 {website => old/website}/book.toml | 0 .../website}/book/1-getting-started/setup.md | 0 {website => old/website}/book/SUMMARY.md | 0 {website => old/website}/book/introduction.md | 0 {website => old/website}/build.sh | 0 {website => old/website}/config.toml | 0 {website => old/website}/content/_index.md | 0 {website => old/website}/content/faq.md | 0 {website => old/website}/content/news.md | 0 {website => old/website}/sass/_markdown.scss | 0 {website => old/website}/sass/_text.scss | 0 {website => old/website}/sass/_ultility.scss | 0 {website => old/website}/sass/juice.scss | 0 {website => old/website}/static/favicon.ico | Bin {website => old/website}/static/normalize.css | 0 {website => old/website}/static/prism.css | 0 {website => old/website}/static/prism.js | 0 {website => old/website}/static/syntax-theme.css | 0 {website => old/website}/templates/_macros.html | 0 {website => old/website}/templates/_variables.html | 0 {website => old/website}/templates/index.html | 0 {website => old/website}/templates/page.html | 0 .../website}/templates/shortcodes/issue.html | 0 588 files changed, 0 insertions(+), 0 deletions(-) rename {.devcontainer => old/.devcontainer}/devcontainer.json (100%) rename {.github => old/.github}/FUNDING.yml (100%) rename {.github => old/.github}/ISSUE_TEMPLATE/bug_report.md (100%) rename {.github => old/.github}/ISSUE_TEMPLATE/config.yml (100%) rename {.github => old/.github}/ISSUE_TEMPLATE/feature_request.md (100%) rename {.github => old/.github}/dependabot.yml (100%) rename {.github => old/.github}/pull_request_template.md (100%) rename {.github => old/.github}/workflows/ci-pr-comments.yml (100%) rename {.github => old/.github}/workflows/ci.yml (100%) rename {.github => old/.github}/workflows/website.yml (100%) rename .gitignore => old/.gitignore (100%) rename CODE_OF_CONDUCT.md => old/CODE_OF_CONDUCT.md (100%) rename CONTRIBUTING.md => old/CONTRIBUTING.md (100%) rename Cargo.toml => old/Cargo.toml (100%) rename LICENSE.txt => old/LICENSE.txt (100%) rename README.md => old/README.md (100%) rename {assets => old/assets}/depgraph.svg (100%) rename {assets => old/assets}/example_pack.zip (100%) rename {assets => old/assets}/logo-256x256.png (100%) rename {assets => old/assets}/logo-64x64.png (100%) rename {assets => old/assets}/logo-full.svg (100%) rename {assets => old/assets}/logo.svg (100%) rename {assets => old/assets}/many-players.png (100%) rename {assets => old/assets}/packet-inspector.png (100%) rename {benches => old/benches}/anvil.rs (100%) rename {benches => old/benches}/block.rs (100%) rename {benches => old/benches}/decode_array.rs (100%) rename {benches => old/benches}/idle.rs (100%) rename {benches => old/benches}/main.rs (100%) rename {benches => old/benches}/many_players.rs (100%) rename {benches => old/benches}/packet.rs (100%) rename {benches => old/benches}/var_int.rs (100%) rename {benches => old/benches}/var_long.rs (100%) rename {crates => old/crates}/README.md (100%) rename {crates => old/crates}/java_string/Cargo.toml (100%) rename {crates => old/crates}/java_string/README.md (100%) rename {crates => old/crates}/java_string/src/cesu8.rs (100%) rename {crates => old/crates}/java_string/src/char.rs (100%) rename {crates => old/crates}/java_string/src/error.rs (100%) rename {crates => old/crates}/java_string/src/iter.rs (100%) rename {crates => old/crates}/java_string/src/lib.rs (100%) rename {crates => old/crates}/java_string/src/owned.rs (100%) rename {crates => old/crates}/java_string/src/pattern.rs (100%) rename {crates => old/crates}/java_string/src/serde.rs (100%) rename {crates => old/crates}/java_string/src/slice.rs (100%) rename {crates => old/crates}/java_string/src/validations.rs (100%) rename {crates => old/crates}/valence_advancement/Cargo.toml (100%) rename {crates => old/crates}/valence_advancement/README.md (100%) rename {crates => old/crates}/valence_advancement/src/event.rs (100%) rename {crates => old/crates}/valence_advancement/src/lib.rs (100%) rename {crates => old/crates}/valence_anvil/Cargo.toml (100%) rename {crates => old/crates}/valence_anvil/README.md (100%) rename {crates => old/crates}/valence_anvil/src/bevy.rs (100%) rename {crates => old/crates}/valence_anvil/src/lib.rs (100%) rename {crates => old/crates}/valence_anvil/src/parsing.rs (100%) rename {crates => old/crates}/valence_boss_bar/Cargo.toml (100%) rename {crates => old/crates}/valence_boss_bar/README.md (100%) rename {crates => old/crates}/valence_boss_bar/src/components.rs (100%) rename {crates => old/crates}/valence_boss_bar/src/lib.rs (100%) rename {crates => old/crates}/valence_build_utils/Cargo.toml (100%) rename {crates => old/crates}/valence_build_utils/README.md (100%) rename {crates => old/crates}/valence_build_utils/src/lib.rs (100%) rename {crates => old/crates}/valence_command/Cargo.toml (100%) rename {crates => old/crates}/valence_command/README.md (100%) rename {crates => old/crates}/valence_command/src/graph.rs (100%) rename {crates => old/crates}/valence_command/src/handler.rs (100%) rename {crates => old/crates}/valence_command/src/lib.rs (100%) rename {crates => old/crates}/valence_command/src/manager.rs (100%) rename {crates => old/crates}/valence_command/src/modifier_value.rs (100%) rename {crates => old/crates}/valence_command/src/parsers.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/angle.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/block_pos.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/bool.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/color.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/column_pos.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/entity_anchor.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/entity_selector.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/gamemode.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/inventory_slot.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/numbers.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/rotation.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/score_holder.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/strings.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/swizzle.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/time.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/vec2.rs (100%) rename {crates => old/crates}/valence_command/src/parsers/vec3.rs (100%) rename {crates => old/crates}/valence_command/src/scopes.rs (100%) rename {crates => old/crates}/valence_command_macros/Cargo.toml (100%) rename {crates => old/crates}/valence_command_macros/README.md (100%) rename {crates => old/crates}/valence_command_macros/src/lib.rs (100%) rename {crates => old/crates}/valence_entity/Cargo.toml (100%) rename {crates => old/crates}/valence_entity/README.md (100%) rename {crates => old/crates}/valence_entity/build.rs (100%) rename {crates => old/crates}/valence_entity/extracted/entities.json (100%) rename {crates => old/crates}/valence_entity/extracted/misc.json (100%) rename {crates => old/crates}/valence_entity/src/active_status_effects.rs (100%) rename {crates => old/crates}/valence_entity/src/attributes.rs (100%) rename {crates => old/crates}/valence_entity/src/flags.rs (100%) rename {crates => old/crates}/valence_entity/src/hitbox.rs (100%) rename {crates => old/crates}/valence_entity/src/lib.rs (100%) rename {crates => old/crates}/valence_entity/src/manager.rs (100%) rename {crates => old/crates}/valence_entity/src/query.rs (100%) rename {crates => old/crates}/valence_entity/src/tracked_data.rs (100%) rename {crates => old/crates}/valence_generated/Cargo.toml (100%) rename {crates => old/crates}/valence_generated/README.md (100%) rename {crates => old/crates}/valence_generated/build/attributes.rs (100%) rename {crates => old/crates}/valence_generated/build/block.rs (100%) rename {crates => old/crates}/valence_generated/build/chunk_view.rs (100%) rename {crates => old/crates}/valence_generated/build/item.rs (100%) rename {crates => old/crates}/valence_generated/build/main.rs (100%) rename {crates => old/crates}/valence_generated/build/packet_id.rs (100%) rename {crates => old/crates}/valence_generated/build/sound.rs (100%) rename {crates => old/crates}/valence_generated/build/status_effects.rs (100%) rename {crates => old/crates}/valence_generated/extracted/attributes.json (100%) rename {crates => old/crates}/valence_generated/extracted/blocks.json (100%) rename {crates => old/crates}/valence_generated/extracted/effects.json (100%) rename {crates => old/crates}/valence_generated/extracted/items.json (100%) rename {crates => old/crates}/valence_generated/extracted/packets.json (100%) rename {crates => old/crates}/valence_generated/extracted/sounds.json (100%) rename {crates => old/crates}/valence_generated/src/block.rs (100%) rename {crates => old/crates}/valence_generated/src/lib.rs (100%) rename {crates => old/crates}/valence_ident/Cargo.toml (100%) rename {crates => old/crates}/valence_ident/README.md (100%) rename {crates => old/crates}/valence_ident/src/lib.rs (100%) rename {crates => old/crates}/valence_ident_macros/Cargo.toml (100%) rename {crates => old/crates}/valence_ident_macros/README.md (100%) rename {crates => old/crates}/valence_ident_macros/src/lib.rs (100%) rename {crates => old/crates}/valence_inventory/Cargo.toml (100%) rename {crates => old/crates}/valence_inventory/README.md (100%) rename {crates => old/crates}/valence_inventory/src/lib.rs (100%) rename {crates => old/crates}/valence_inventory/src/player_inventory.rs (100%) rename {crates => old/crates}/valence_inventory/src/validate.rs (100%) rename {crates => old/crates}/valence_lang/Cargo.toml (100%) rename {crates => old/crates}/valence_lang/README.md (100%) rename {crates => old/crates}/valence_lang/build.rs (100%) rename {crates => old/crates}/valence_lang/extracted/translation_keys.json (100%) rename {crates => old/crates}/valence_lang/src/lib.rs (100%) rename {crates => old/crates}/valence_math/Cargo.toml (100%) rename {crates => old/crates}/valence_math/README.md (100%) rename {crates => old/crates}/valence_math/src/aabb.rs (100%) rename {crates => old/crates}/valence_math/src/lib.rs (100%) rename {crates => old/crates}/valence_nbt/Cargo.toml (100%) rename {crates => old/crates}/valence_nbt/README.md (100%) rename {crates => old/crates}/valence_nbt/src/binary.rs (100%) rename {crates => old/crates}/valence_nbt/src/binary/decode.rs (100%) rename {crates => old/crates}/valence_nbt/src/binary/encode.rs (100%) rename {crates => old/crates}/valence_nbt/src/binary/error.rs (100%) rename {crates => old/crates}/valence_nbt/src/binary/modified_utf8.rs (100%) rename {crates => old/crates}/valence_nbt/src/binary/tests.rs (100%) rename {crates => old/crates}/valence_nbt/src/compound.rs (100%) rename {crates => old/crates}/valence_nbt/src/conv.rs (100%) rename {crates => old/crates}/valence_nbt/src/lib.rs (100%) rename {crates => old/crates}/valence_nbt/src/list.rs (100%) rename {crates => old/crates}/valence_nbt/src/serde.rs (100%) rename {crates => old/crates}/valence_nbt/src/serde/de.rs (100%) rename {crates => old/crates}/valence_nbt/src/serde/ser.rs (100%) rename {crates => old/crates}/valence_nbt/src/serde/tests.rs (100%) rename {crates => old/crates}/valence_nbt/src/snbt.rs (100%) rename {crates => old/crates}/valence_nbt/src/tag.rs (100%) rename {crates => old/crates}/valence_nbt/src/value.rs (100%) rename {crates => old/crates}/valence_network/Cargo.toml (100%) rename {crates => old/crates}/valence_network/README.md (100%) rename {crates => old/crates}/valence_network/src/byte_channel.rs (100%) rename {crates => old/crates}/valence_network/src/connect.rs (100%) rename {crates => old/crates}/valence_network/src/legacy_ping.rs (100%) rename {crates => old/crates}/valence_network/src/lib.rs (100%) rename {crates => old/crates}/valence_network/src/packet_io.rs (100%) rename {crates => old/crates}/valence_player_list/Cargo.toml (100%) rename {crates => old/crates}/valence_player_list/README.md (100%) rename {crates => old/crates}/valence_player_list/src/lib.rs (100%) rename {crates => old/crates}/valence_protocol/Cargo.toml (100%) rename {crates => old/crates}/valence_protocol/README.md (100%) rename {crates => old/crates}/valence_protocol/src/array.rs (100%) rename {crates => old/crates}/valence_protocol/src/biome_pos.rs (100%) rename {crates => old/crates}/valence_protocol/src/bit_set.rs (100%) rename {crates => old/crates}/valence_protocol/src/block_pos.rs (100%) rename {crates => old/crates}/valence_protocol/src/bounded.rs (100%) rename {crates => old/crates}/valence_protocol/src/byte_angle.rs (100%) rename {crates => old/crates}/valence_protocol/src/chunk_pos.rs (100%) rename {crates => old/crates}/valence_protocol/src/chunk_section_pos.rs (100%) rename {crates => old/crates}/valence_protocol/src/decode.rs (100%) rename {crates => old/crates}/valence_protocol/src/difficulty.rs (100%) rename {crates => old/crates}/valence_protocol/src/direction.rs (100%) rename {crates => old/crates}/valence_protocol/src/encode.rs (100%) rename {crates => old/crates}/valence_protocol/src/game_mode.rs (100%) rename {crates => old/crates}/valence_protocol/src/global_pos.rs (100%) rename {crates => old/crates}/valence_protocol/src/hand.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/map.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/math.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/other.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/pointer.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/primitive.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/sequence.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/string.rs (100%) rename {crates => old/crates}/valence_protocol/src/impls/tuple.rs (100%) rename {crates => old/crates}/valence_protocol/src/item.rs (100%) rename {crates => old/crates}/valence_protocol/src/lib.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/handshaking/handshake_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_compression_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_disconnect_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_hello_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_hello_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_key_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_query_request_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_query_response_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/login/login_success_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/advancement_tab_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/advancement_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/block_breaking_progress_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/block_entity_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/block_event_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/block_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/boat_paddle_state_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/book_update_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/boss_bar_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/bundle_splitter_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/button_click_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chat_message_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chat_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chat_suggestions_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chunk_biome_data_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chunk_data_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chunk_delta_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chunk_load_distance_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/chunk_render_distance_center_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/clear_title_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/click_slot_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/client_command_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/client_settings_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/client_status_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/close_handled_screen_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/close_screen_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/command_execution_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/command_suggestions_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/command_tree_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/cooldown_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/craft_failed_response_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/craft_request_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/creative_inventory_action_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/custom_payload_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/custom_payload_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/damage_tilt_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/death_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/difficulty_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/disconnect_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/end_combat_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/enter_combat_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entities_destroy_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_animation_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_attach_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_attributes_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_damage_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_equipment_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_passengers_set_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_position_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_set_head_yaw_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_spawn_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_status_effect_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_status_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_tracker_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/entity_velocity_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/experience_bar_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/experience_orb_spawn_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/explosion_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/features_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/full_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/game_join_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/game_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/game_state_change_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/hand_swing_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/health_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/inventory_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/item_pickup_animation_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/jigsaw_generating_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/keep_alive_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/keep_alive_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/light_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/look_and_on_ground_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/look_at_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/map_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/message_acknowledgment_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/move_relative_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/nbt_query_response_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/on_ground_only_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/open_horse_screen_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/open_screen_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/open_written_book_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/overlay_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/particle_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/pick_from_inventory_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/play_ping_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/play_pong_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/play_sound_from_entity_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/play_sound_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_abilities_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_action_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_action_response_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_input_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_interact_block_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_interact_entity_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_interact_item_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_list_header_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_list_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_position_look_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_remove_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_respawn_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_session_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_spawn_position_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/player_spawn_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/position_and_on_ground_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/profileless_chat_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/query_block_nbt_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/query_entity_nbt_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/recipe_book_data_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/recipe_category_options_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/remove_entity_status_effect_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/remove_message_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/rename_item_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/request_command_completions_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/resource_pack_send_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/resource_pack_status_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/rotate_and_move_relative_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/rotate_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/scoreboard_display_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/scoreboard_objective_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/scoreboard_player_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/screen_handler_property_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/screen_handler_slot_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/select_advancement_tab_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/select_merchant_trade_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/server_metadata_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/set_camera_entity_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/set_trade_offers_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/sign_editor_open_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/simulation_distance_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/spectator_teleport_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/statistics_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/stop_sound_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/subtitle_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/synchronize_recipes_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/synchronize_tags_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/team_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/teleport_confirm_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/title_fade_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/title_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/unload_chunk_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/unlock_recipes_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_beacon_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_command_block_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_command_block_minecart_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_difficulty_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_difficulty_lock_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_jigsaw_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_player_abilities_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_selected_slot_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_selected_slot_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_sign_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/update_structure_block_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/vehicle_move_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/vehicle_move_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_center_changed_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_initialize_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_interpolate_size_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_size_changed_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_warning_blocks_changed_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_border_warning_time_changed_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_event_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/play/world_time_update_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/status.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/status/query_ping_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/status/query_pong_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/status/query_request_c2s.rs (100%) rename {crates => old/crates}/valence_protocol/src/packets/status/query_response_s2c.rs (100%) rename {crates => old/crates}/valence_protocol/src/profile.rs (100%) rename {crates => old/crates}/valence_protocol/src/raw.rs (100%) rename {crates => old/crates}/valence_protocol/src/sound.rs (100%) rename {crates => old/crates}/valence_protocol/src/var_int.rs (100%) rename {crates => old/crates}/valence_protocol/src/var_long.rs (100%) rename {crates => old/crates}/valence_protocol/src/velocity.rs (100%) rename {crates => old/crates}/valence_protocol_macros/Cargo.toml (100%) rename {crates => old/crates}/valence_protocol_macros/README.md (100%) rename {crates => old/crates}/valence_protocol_macros/src/decode.rs (100%) rename {crates => old/crates}/valence_protocol_macros/src/encode.rs (100%) rename {crates => old/crates}/valence_protocol_macros/src/lib.rs (100%) rename {crates => old/crates}/valence_protocol_macros/src/packet.rs (100%) rename {crates => old/crates}/valence_registry/Cargo.toml (100%) rename {crates => old/crates}/valence_registry/README.md (100%) rename {crates => old/crates}/valence_registry/extracted/registry_codec.dat (100%) rename {crates => old/crates}/valence_registry/extracted/tags.json (100%) rename {crates => old/crates}/valence_registry/src/biome.rs (100%) rename {crates => old/crates}/valence_registry/src/codec.rs (100%) rename {crates => old/crates}/valence_registry/src/dimension_type.rs (100%) rename {crates => old/crates}/valence_registry/src/lib.rs (100%) rename {crates => old/crates}/valence_registry/src/tags.rs (100%) rename {crates => old/crates}/valence_scoreboard/Cargo.toml (100%) rename {crates => old/crates}/valence_scoreboard/README.md (100%) rename {crates => old/crates}/valence_scoreboard/src/components.rs (100%) rename {crates => old/crates}/valence_scoreboard/src/lib.rs (100%) rename {crates => old/crates}/valence_server/Cargo.toml (100%) rename {crates => old/crates}/valence_server/README.md (100%) rename {crates => old/crates}/valence_server/src/abilities.rs (100%) rename {crates => old/crates}/valence_server/src/action.rs (100%) rename {crates => old/crates}/valence_server/src/brand.rs (100%) rename {crates => old/crates}/valence_server/src/chunk_view.rs (100%) rename {crates => old/crates}/valence_server/src/client.rs (100%) rename {crates => old/crates}/valence_server/src/client_command.rs (100%) rename {crates => old/crates}/valence_server/src/client_settings.rs (100%) rename {crates => old/crates}/valence_server/src/custom_payload.rs (100%) rename {crates => old/crates}/valence_server/src/event_loop.rs (100%) rename {crates => old/crates}/valence_server/src/hand_swing.rs (100%) rename {crates => old/crates}/valence_server/src/interact_block.rs (100%) rename {crates => old/crates}/valence_server/src/interact_entity.rs (100%) rename {crates => old/crates}/valence_server/src/interact_item.rs (100%) rename {crates => old/crates}/valence_server/src/keepalive.rs (100%) rename {crates => old/crates}/valence_server/src/layer.rs (100%) rename {crates => old/crates}/valence_server/src/layer/bvh.rs (100%) rename {crates => old/crates}/valence_server/src/layer/chunk.rs (100%) rename {crates => old/crates}/valence_server/src/layer/chunk/chunk.rs (100%) rename {crates => old/crates}/valence_server/src/layer/chunk/loaded.rs (100%) rename {crates => old/crates}/valence_server/src/layer/chunk/paletted_container.rs (100%) rename {crates => old/crates}/valence_server/src/layer/chunk/unloaded.rs (100%) rename {crates => old/crates}/valence_server/src/layer/entity.rs (100%) rename {crates => old/crates}/valence_server/src/layer/message.rs (100%) rename {crates => old/crates}/valence_server/src/lib.rs (100%) rename {crates => old/crates}/valence_server/src/message.rs (100%) rename {crates => old/crates}/valence_server/src/movement.rs (100%) rename {crates => old/crates}/valence_server/src/op_level.rs (100%) rename {crates => old/crates}/valence_server/src/resource_pack.rs (100%) rename {crates => old/crates}/valence_server/src/spawn.rs (100%) rename {crates => old/crates}/valence_server/src/status.rs (100%) rename {crates => old/crates}/valence_server/src/status_effect.rs (100%) rename {crates => old/crates}/valence_server/src/teleport.rs (100%) rename {crates => old/crates}/valence_server/src/title.rs (100%) rename {crates => old/crates}/valence_server_common/Cargo.toml (100%) rename {crates => old/crates}/valence_server_common/README.md (100%) rename {crates => old/crates}/valence_server_common/src/despawn.rs (100%) rename {crates => old/crates}/valence_server_common/src/lib.rs (100%) rename {crates => old/crates}/valence_server_common/src/uuid.rs (100%) rename {crates => old/crates}/valence_spatial/Cargo.toml (100%) rename {crates => old/crates}/valence_spatial/README.md (100%) rename {crates => old/crates}/valence_spatial/src/bvh.rs (100%) rename {crates => old/crates}/valence_spatial/src/lib.rs (100%) rename {crates => old/crates}/valence_text/Cargo.toml (100%) rename {crates => old/crates}/valence_text/README.md (100%) rename {crates => old/crates}/valence_text/src/color.rs (100%) rename {crates => old/crates}/valence_text/src/into_text.rs (100%) rename {crates => old/crates}/valence_text/src/lib.rs (100%) rename {crates => old/crates}/valence_text/src/tests.rs (100%) rename {crates => old/crates}/valence_weather/Cargo.toml (100%) rename {crates => old/crates}/valence_weather/README.md (100%) rename {crates => old/crates}/valence_weather/src/lib.rs (100%) rename {crates => old/crates}/valence_weather/src/packet.rs (100%) rename {crates => old/crates}/valence_world_border/Cargo.toml (100%) rename {crates => old/crates}/valence_world_border/README.md (100%) rename {crates => old/crates}/valence_world_border/src/lib.rs (100%) rename {examples => old/examples}/advancement.rs (100%) rename {examples => old/examples}/anvil_loading.rs (100%) rename {examples => old/examples}/bench_players.rs (100%) rename {examples => old/examples}/biomes.rs (100%) rename {examples => old/examples}/block_entities.rs (100%) rename {examples => old/examples}/boss_bar.rs (100%) rename {examples => old/examples}/building.rs (100%) rename {examples => old/examples}/chest.rs (100%) rename {examples => old/examples}/combat.rs (100%) rename {examples => old/examples}/command.rs (100%) rename {examples => old/examples}/cow_sphere.rs (100%) rename {examples => old/examples}/ctf.rs (100%) rename {examples => old/examples}/custom_npc.rs (100%) rename {examples => old/examples}/death.rs (100%) rename {examples => old/examples}/entity_hitbox.rs (100%) rename {examples => old/examples}/game_of_life.rs (100%) rename {examples => old/examples}/parkour.rs (100%) rename {examples => old/examples}/particles.rs (100%) rename {examples => old/examples}/player_list.rs (100%) rename {examples => old/examples}/potions.rs (100%) rename {examples => old/examples}/resource_pack.rs (100%) rename {examples => old/examples}/server_list_ping.rs (100%) rename {examples => old/examples}/terrain.rs (100%) rename {examples => old/examples}/text.rs (100%) rename {examples => old/examples}/weather.rs (100%) rename {examples => old/examples}/world_border.rs (100%) rename {extractor => old/extractor}/README.md (100%) rename {extractor => old/extractor}/build.gradle (100%) rename {extractor => old/extractor}/copy_extractor_output.sh (100%) rename {extractor => old/extractor}/gradle.properties (100%) rename {extractor => old/extractor}/gradle/wrapper/gradle-wrapper.jar (100%) rename {extractor => old/extractor}/gradle/wrapper/gradle-wrapper.properties (100%) rename {extractor => old/extractor}/gradlew (100%) rename {extractor => old/extractor}/gradlew.bat (100%) rename {extractor => old/extractor}/settings.gradle (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/ClassComparator.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/DummyPlayerEntity.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/DummyWorld.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/Main.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/RegistryKeyComparator.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/ValenceUtils.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Attributes.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Biomes.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Blocks.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Codec.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Effects.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Enchants.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Entities.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Items.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Misc.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Packets.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Sounds.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/Tags.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java (100%) rename {extractor => old/extractor}/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java (100%) rename {extractor => old/extractor}/src/main/resources/extractor.mixins.json (100%) rename {extractor => old/extractor}/src/main/resources/fabric.mod.json (100%) rename rustfmt.toml => old/rustfmt.toml (100%) rename {src => old/src}/lib.rs (100%) rename {src => old/src}/testing.rs (100%) rename {src => old/src}/tests.rs (100%) rename {src => old/src}/tests/boss_bar.rs (100%) rename {src => old/src}/tests/client.rs (100%) rename {src => old/src}/tests/example.rs (100%) rename {src => old/src}/tests/hunger.rs (100%) rename {src => old/src}/tests/inventory.rs (100%) rename {src => old/src}/tests/layer.rs (100%) rename {src => old/src}/tests/player_list.rs (100%) rename {src => old/src}/tests/potions.rs (100%) rename {src => old/src}/tests/scoreboard.rs (100%) rename {src => old/src}/tests/weather.rs (100%) rename {src => old/src}/tests/world_border.rs (100%) rename {tools => old/tools}/dump_schedule/Cargo.toml (100%) rename {tools => old/tools}/dump_schedule/README.md (100%) rename {tools => old/tools}/dump_schedule/src/main.rs (100%) rename {tools => old/tools}/packet_inspector/Cargo.toml (100%) rename {tools => old/tools}/packet_inspector/README.md (100%) rename {tools => old/tools}/packet_inspector/build.rs (100%) rename {tools => old/tools}/packet_inspector/extracted/packets.json (100%) rename {tools => old/tools}/packet_inspector/src/app.rs (100%) rename {tools => old/tools}/packet_inspector/src/app/connection.rs (100%) rename {tools => old/tools}/packet_inspector/src/app/filter.rs (100%) rename {tools => old/tools}/packet_inspector/src/app/hex_viewer.rs (100%) rename {tools => old/tools}/packet_inspector/src/app/packet_list.rs (100%) rename {tools => old/tools}/packet_inspector/src/app/text_viewer.rs (100%) rename {tools => old/tools}/packet_inspector/src/lib.rs (100%) rename {tools => old/tools}/packet_inspector/src/main.rs (100%) rename {tools => old/tools}/packet_inspector/src/main_cli.rs (100%) rename {tools => old/tools}/packet_inspector/src/packet_io.rs (100%) rename {tools => old/tools}/packet_inspector/src/packet_registry.rs (100%) rename {tools => old/tools}/packet_inspector/src/shared_state.rs (100%) rename {tools => old/tools}/packet_inspector/src/tri_checkbox.rs (100%) rename {tools => old/tools}/playground/Cargo.toml (100%) rename {tools => old/tools}/playground/README.md (100%) rename {tools => old/tools}/playground/build.rs (100%) rename {tools => old/tools}/playground/src/.gitignore (100%) rename {tools => old/tools}/playground/src/extras.rs (100%) rename {tools => old/tools}/playground/src/main.rs (100%) rename {tools => old/tools}/playground/src/playground.template.rs (100%) rename {tools => old/tools}/stresser/Cargo.toml (100%) rename {tools => old/tools}/stresser/README.md (100%) rename {tools => old/tools}/stresser/src/args.rs (100%) rename {tools => old/tools}/stresser/src/main.rs (100%) rename {tools => old/tools}/stresser/src/stresser.rs (100%) rename typos.toml => old/typos.toml (100%) rename {website => old/website}/.gitignore (100%) rename {website => old/website}/README.md (100%) rename {website => old/website}/book.toml (100%) rename {website => old/website}/book/1-getting-started/setup.md (100%) rename {website => old/website}/book/SUMMARY.md (100%) rename {website => old/website}/book/introduction.md (100%) rename {website => old/website}/build.sh (100%) rename {website => old/website}/config.toml (100%) rename {website => old/website}/content/_index.md (100%) rename {website => old/website}/content/faq.md (100%) rename {website => old/website}/content/news.md (100%) rename {website => old/website}/sass/_markdown.scss (100%) rename {website => old/website}/sass/_text.scss (100%) rename {website => old/website}/sass/_ultility.scss (100%) rename {website => old/website}/sass/juice.scss (100%) rename {website => old/website}/static/favicon.ico (100%) rename {website => old/website}/static/normalize.css (100%) rename {website => old/website}/static/prism.css (100%) rename {website => old/website}/static/prism.js (100%) rename {website => old/website}/static/syntax-theme.css (100%) rename {website => old/website}/templates/_macros.html (100%) rename {website => old/website}/templates/_variables.html (100%) rename {website => old/website}/templates/index.html (100%) rename {website => old/website}/templates/page.html (100%) rename {website => old/website}/templates/shortcodes/issue.html (100%) diff --git a/.devcontainer/devcontainer.json b/old/.devcontainer/devcontainer.json similarity index 100% rename from .devcontainer/devcontainer.json rename to old/.devcontainer/devcontainer.json diff --git a/.github/FUNDING.yml b/old/.github/FUNDING.yml similarity index 100% rename from .github/FUNDING.yml rename to old/.github/FUNDING.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/old/.github/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to old/.github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/old/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yml rename to old/.github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/old/.github/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to old/.github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/dependabot.yml b/old/.github/dependabot.yml similarity index 100% rename from .github/dependabot.yml rename to old/.github/dependabot.yml diff --git a/.github/pull_request_template.md b/old/.github/pull_request_template.md similarity index 100% rename from .github/pull_request_template.md rename to old/.github/pull_request_template.md diff --git a/.github/workflows/ci-pr-comments.yml b/old/.github/workflows/ci-pr-comments.yml similarity index 100% rename from .github/workflows/ci-pr-comments.yml rename to old/.github/workflows/ci-pr-comments.yml diff --git a/.github/workflows/ci.yml b/old/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/ci.yml rename to old/.github/workflows/ci.yml diff --git a/.github/workflows/website.yml b/old/.github/workflows/website.yml similarity index 100% rename from .github/workflows/website.yml rename to old/.github/workflows/website.yml diff --git a/.gitignore b/old/.gitignore similarity index 100% rename from .gitignore rename to old/.gitignore diff --git a/CODE_OF_CONDUCT.md b/old/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to old/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/old/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to old/CONTRIBUTING.md diff --git a/Cargo.toml b/old/Cargo.toml similarity index 100% rename from Cargo.toml rename to old/Cargo.toml diff --git a/LICENSE.txt b/old/LICENSE.txt similarity index 100% rename from LICENSE.txt rename to old/LICENSE.txt diff --git a/README.md b/old/README.md similarity index 100% rename from README.md rename to old/README.md diff --git a/assets/depgraph.svg b/old/assets/depgraph.svg similarity index 100% rename from assets/depgraph.svg rename to old/assets/depgraph.svg diff --git a/assets/example_pack.zip b/old/assets/example_pack.zip similarity index 100% rename from assets/example_pack.zip rename to old/assets/example_pack.zip diff --git a/assets/logo-256x256.png b/old/assets/logo-256x256.png similarity index 100% rename from assets/logo-256x256.png rename to old/assets/logo-256x256.png diff --git a/assets/logo-64x64.png b/old/assets/logo-64x64.png similarity index 100% rename from assets/logo-64x64.png rename to old/assets/logo-64x64.png diff --git a/assets/logo-full.svg b/old/assets/logo-full.svg similarity index 100% rename from assets/logo-full.svg rename to old/assets/logo-full.svg diff --git a/assets/logo.svg b/old/assets/logo.svg similarity index 100% rename from assets/logo.svg rename to old/assets/logo.svg diff --git a/assets/many-players.png b/old/assets/many-players.png similarity index 100% rename from assets/many-players.png rename to old/assets/many-players.png diff --git a/assets/packet-inspector.png b/old/assets/packet-inspector.png similarity index 100% rename from assets/packet-inspector.png rename to old/assets/packet-inspector.png diff --git a/benches/anvil.rs b/old/benches/anvil.rs similarity index 100% rename from benches/anvil.rs rename to old/benches/anvil.rs diff --git a/benches/block.rs b/old/benches/block.rs similarity index 100% rename from benches/block.rs rename to old/benches/block.rs diff --git a/benches/decode_array.rs b/old/benches/decode_array.rs similarity index 100% rename from benches/decode_array.rs rename to old/benches/decode_array.rs diff --git a/benches/idle.rs b/old/benches/idle.rs similarity index 100% rename from benches/idle.rs rename to old/benches/idle.rs diff --git a/benches/main.rs b/old/benches/main.rs similarity index 100% rename from benches/main.rs rename to old/benches/main.rs diff --git a/benches/many_players.rs b/old/benches/many_players.rs similarity index 100% rename from benches/many_players.rs rename to old/benches/many_players.rs diff --git a/benches/packet.rs b/old/benches/packet.rs similarity index 100% rename from benches/packet.rs rename to old/benches/packet.rs diff --git a/benches/var_int.rs b/old/benches/var_int.rs similarity index 100% rename from benches/var_int.rs rename to old/benches/var_int.rs diff --git a/benches/var_long.rs b/old/benches/var_long.rs similarity index 100% rename from benches/var_long.rs rename to old/benches/var_long.rs diff --git a/crates/README.md b/old/crates/README.md similarity index 100% rename from crates/README.md rename to old/crates/README.md diff --git a/crates/java_string/Cargo.toml b/old/crates/java_string/Cargo.toml similarity index 100% rename from crates/java_string/Cargo.toml rename to old/crates/java_string/Cargo.toml diff --git a/crates/java_string/README.md b/old/crates/java_string/README.md similarity index 100% rename from crates/java_string/README.md rename to old/crates/java_string/README.md diff --git a/crates/java_string/src/cesu8.rs b/old/crates/java_string/src/cesu8.rs similarity index 100% rename from crates/java_string/src/cesu8.rs rename to old/crates/java_string/src/cesu8.rs diff --git a/crates/java_string/src/char.rs b/old/crates/java_string/src/char.rs similarity index 100% rename from crates/java_string/src/char.rs rename to old/crates/java_string/src/char.rs diff --git a/crates/java_string/src/error.rs b/old/crates/java_string/src/error.rs similarity index 100% rename from crates/java_string/src/error.rs rename to old/crates/java_string/src/error.rs diff --git a/crates/java_string/src/iter.rs b/old/crates/java_string/src/iter.rs similarity index 100% rename from crates/java_string/src/iter.rs rename to old/crates/java_string/src/iter.rs diff --git a/crates/java_string/src/lib.rs b/old/crates/java_string/src/lib.rs similarity index 100% rename from crates/java_string/src/lib.rs rename to old/crates/java_string/src/lib.rs diff --git a/crates/java_string/src/owned.rs b/old/crates/java_string/src/owned.rs similarity index 100% rename from crates/java_string/src/owned.rs rename to old/crates/java_string/src/owned.rs diff --git a/crates/java_string/src/pattern.rs b/old/crates/java_string/src/pattern.rs similarity index 100% rename from crates/java_string/src/pattern.rs rename to old/crates/java_string/src/pattern.rs diff --git a/crates/java_string/src/serde.rs b/old/crates/java_string/src/serde.rs similarity index 100% rename from crates/java_string/src/serde.rs rename to old/crates/java_string/src/serde.rs diff --git a/crates/java_string/src/slice.rs b/old/crates/java_string/src/slice.rs similarity index 100% rename from crates/java_string/src/slice.rs rename to old/crates/java_string/src/slice.rs diff --git a/crates/java_string/src/validations.rs b/old/crates/java_string/src/validations.rs similarity index 100% rename from crates/java_string/src/validations.rs rename to old/crates/java_string/src/validations.rs diff --git a/crates/valence_advancement/Cargo.toml b/old/crates/valence_advancement/Cargo.toml similarity index 100% rename from crates/valence_advancement/Cargo.toml rename to old/crates/valence_advancement/Cargo.toml diff --git a/crates/valence_advancement/README.md b/old/crates/valence_advancement/README.md similarity index 100% rename from crates/valence_advancement/README.md rename to old/crates/valence_advancement/README.md diff --git a/crates/valence_advancement/src/event.rs b/old/crates/valence_advancement/src/event.rs similarity index 100% rename from crates/valence_advancement/src/event.rs rename to old/crates/valence_advancement/src/event.rs diff --git a/crates/valence_advancement/src/lib.rs b/old/crates/valence_advancement/src/lib.rs similarity index 100% rename from crates/valence_advancement/src/lib.rs rename to old/crates/valence_advancement/src/lib.rs diff --git a/crates/valence_anvil/Cargo.toml b/old/crates/valence_anvil/Cargo.toml similarity index 100% rename from crates/valence_anvil/Cargo.toml rename to old/crates/valence_anvil/Cargo.toml diff --git a/crates/valence_anvil/README.md b/old/crates/valence_anvil/README.md similarity index 100% rename from crates/valence_anvil/README.md rename to old/crates/valence_anvil/README.md diff --git a/crates/valence_anvil/src/bevy.rs b/old/crates/valence_anvil/src/bevy.rs similarity index 100% rename from crates/valence_anvil/src/bevy.rs rename to old/crates/valence_anvil/src/bevy.rs diff --git a/crates/valence_anvil/src/lib.rs b/old/crates/valence_anvil/src/lib.rs similarity index 100% rename from crates/valence_anvil/src/lib.rs rename to old/crates/valence_anvil/src/lib.rs diff --git a/crates/valence_anvil/src/parsing.rs b/old/crates/valence_anvil/src/parsing.rs similarity index 100% rename from crates/valence_anvil/src/parsing.rs rename to old/crates/valence_anvil/src/parsing.rs diff --git a/crates/valence_boss_bar/Cargo.toml b/old/crates/valence_boss_bar/Cargo.toml similarity index 100% rename from crates/valence_boss_bar/Cargo.toml rename to old/crates/valence_boss_bar/Cargo.toml diff --git a/crates/valence_boss_bar/README.md b/old/crates/valence_boss_bar/README.md similarity index 100% rename from crates/valence_boss_bar/README.md rename to old/crates/valence_boss_bar/README.md diff --git a/crates/valence_boss_bar/src/components.rs b/old/crates/valence_boss_bar/src/components.rs similarity index 100% rename from crates/valence_boss_bar/src/components.rs rename to old/crates/valence_boss_bar/src/components.rs diff --git a/crates/valence_boss_bar/src/lib.rs b/old/crates/valence_boss_bar/src/lib.rs similarity index 100% rename from crates/valence_boss_bar/src/lib.rs rename to old/crates/valence_boss_bar/src/lib.rs diff --git a/crates/valence_build_utils/Cargo.toml b/old/crates/valence_build_utils/Cargo.toml similarity index 100% rename from crates/valence_build_utils/Cargo.toml rename to old/crates/valence_build_utils/Cargo.toml diff --git a/crates/valence_build_utils/README.md b/old/crates/valence_build_utils/README.md similarity index 100% rename from crates/valence_build_utils/README.md rename to old/crates/valence_build_utils/README.md diff --git a/crates/valence_build_utils/src/lib.rs b/old/crates/valence_build_utils/src/lib.rs similarity index 100% rename from crates/valence_build_utils/src/lib.rs rename to old/crates/valence_build_utils/src/lib.rs diff --git a/crates/valence_command/Cargo.toml b/old/crates/valence_command/Cargo.toml similarity index 100% rename from crates/valence_command/Cargo.toml rename to old/crates/valence_command/Cargo.toml diff --git a/crates/valence_command/README.md b/old/crates/valence_command/README.md similarity index 100% rename from crates/valence_command/README.md rename to old/crates/valence_command/README.md diff --git a/crates/valence_command/src/graph.rs b/old/crates/valence_command/src/graph.rs similarity index 100% rename from crates/valence_command/src/graph.rs rename to old/crates/valence_command/src/graph.rs diff --git a/crates/valence_command/src/handler.rs b/old/crates/valence_command/src/handler.rs similarity index 100% rename from crates/valence_command/src/handler.rs rename to old/crates/valence_command/src/handler.rs diff --git a/crates/valence_command/src/lib.rs b/old/crates/valence_command/src/lib.rs similarity index 100% rename from crates/valence_command/src/lib.rs rename to old/crates/valence_command/src/lib.rs diff --git a/crates/valence_command/src/manager.rs b/old/crates/valence_command/src/manager.rs similarity index 100% rename from crates/valence_command/src/manager.rs rename to old/crates/valence_command/src/manager.rs diff --git a/crates/valence_command/src/modifier_value.rs b/old/crates/valence_command/src/modifier_value.rs similarity index 100% rename from crates/valence_command/src/modifier_value.rs rename to old/crates/valence_command/src/modifier_value.rs diff --git a/crates/valence_command/src/parsers.rs b/old/crates/valence_command/src/parsers.rs similarity index 100% rename from crates/valence_command/src/parsers.rs rename to old/crates/valence_command/src/parsers.rs diff --git a/crates/valence_command/src/parsers/angle.rs b/old/crates/valence_command/src/parsers/angle.rs similarity index 100% rename from crates/valence_command/src/parsers/angle.rs rename to old/crates/valence_command/src/parsers/angle.rs diff --git a/crates/valence_command/src/parsers/block_pos.rs b/old/crates/valence_command/src/parsers/block_pos.rs similarity index 100% rename from crates/valence_command/src/parsers/block_pos.rs rename to old/crates/valence_command/src/parsers/block_pos.rs diff --git a/crates/valence_command/src/parsers/bool.rs b/old/crates/valence_command/src/parsers/bool.rs similarity index 100% rename from crates/valence_command/src/parsers/bool.rs rename to old/crates/valence_command/src/parsers/bool.rs diff --git a/crates/valence_command/src/parsers/color.rs b/old/crates/valence_command/src/parsers/color.rs similarity index 100% rename from crates/valence_command/src/parsers/color.rs rename to old/crates/valence_command/src/parsers/color.rs diff --git a/crates/valence_command/src/parsers/column_pos.rs b/old/crates/valence_command/src/parsers/column_pos.rs similarity index 100% rename from crates/valence_command/src/parsers/column_pos.rs rename to old/crates/valence_command/src/parsers/column_pos.rs diff --git a/crates/valence_command/src/parsers/entity_anchor.rs b/old/crates/valence_command/src/parsers/entity_anchor.rs similarity index 100% rename from crates/valence_command/src/parsers/entity_anchor.rs rename to old/crates/valence_command/src/parsers/entity_anchor.rs diff --git a/crates/valence_command/src/parsers/entity_selector.rs b/old/crates/valence_command/src/parsers/entity_selector.rs similarity index 100% rename from crates/valence_command/src/parsers/entity_selector.rs rename to old/crates/valence_command/src/parsers/entity_selector.rs diff --git a/crates/valence_command/src/parsers/gamemode.rs b/old/crates/valence_command/src/parsers/gamemode.rs similarity index 100% rename from crates/valence_command/src/parsers/gamemode.rs rename to old/crates/valence_command/src/parsers/gamemode.rs diff --git a/crates/valence_command/src/parsers/inventory_slot.rs b/old/crates/valence_command/src/parsers/inventory_slot.rs similarity index 100% rename from crates/valence_command/src/parsers/inventory_slot.rs rename to old/crates/valence_command/src/parsers/inventory_slot.rs diff --git a/crates/valence_command/src/parsers/numbers.rs b/old/crates/valence_command/src/parsers/numbers.rs similarity index 100% rename from crates/valence_command/src/parsers/numbers.rs rename to old/crates/valence_command/src/parsers/numbers.rs diff --git a/crates/valence_command/src/parsers/rotation.rs b/old/crates/valence_command/src/parsers/rotation.rs similarity index 100% rename from crates/valence_command/src/parsers/rotation.rs rename to old/crates/valence_command/src/parsers/rotation.rs diff --git a/crates/valence_command/src/parsers/score_holder.rs b/old/crates/valence_command/src/parsers/score_holder.rs similarity index 100% rename from crates/valence_command/src/parsers/score_holder.rs rename to old/crates/valence_command/src/parsers/score_holder.rs diff --git a/crates/valence_command/src/parsers/strings.rs b/old/crates/valence_command/src/parsers/strings.rs similarity index 100% rename from crates/valence_command/src/parsers/strings.rs rename to old/crates/valence_command/src/parsers/strings.rs diff --git a/crates/valence_command/src/parsers/swizzle.rs b/old/crates/valence_command/src/parsers/swizzle.rs similarity index 100% rename from crates/valence_command/src/parsers/swizzle.rs rename to old/crates/valence_command/src/parsers/swizzle.rs diff --git a/crates/valence_command/src/parsers/time.rs b/old/crates/valence_command/src/parsers/time.rs similarity index 100% rename from crates/valence_command/src/parsers/time.rs rename to old/crates/valence_command/src/parsers/time.rs diff --git a/crates/valence_command/src/parsers/vec2.rs b/old/crates/valence_command/src/parsers/vec2.rs similarity index 100% rename from crates/valence_command/src/parsers/vec2.rs rename to old/crates/valence_command/src/parsers/vec2.rs diff --git a/crates/valence_command/src/parsers/vec3.rs b/old/crates/valence_command/src/parsers/vec3.rs similarity index 100% rename from crates/valence_command/src/parsers/vec3.rs rename to old/crates/valence_command/src/parsers/vec3.rs diff --git a/crates/valence_command/src/scopes.rs b/old/crates/valence_command/src/scopes.rs similarity index 100% rename from crates/valence_command/src/scopes.rs rename to old/crates/valence_command/src/scopes.rs diff --git a/crates/valence_command_macros/Cargo.toml b/old/crates/valence_command_macros/Cargo.toml similarity index 100% rename from crates/valence_command_macros/Cargo.toml rename to old/crates/valence_command_macros/Cargo.toml diff --git a/crates/valence_command_macros/README.md b/old/crates/valence_command_macros/README.md similarity index 100% rename from crates/valence_command_macros/README.md rename to old/crates/valence_command_macros/README.md diff --git a/crates/valence_command_macros/src/lib.rs b/old/crates/valence_command_macros/src/lib.rs similarity index 100% rename from crates/valence_command_macros/src/lib.rs rename to old/crates/valence_command_macros/src/lib.rs diff --git a/crates/valence_entity/Cargo.toml b/old/crates/valence_entity/Cargo.toml similarity index 100% rename from crates/valence_entity/Cargo.toml rename to old/crates/valence_entity/Cargo.toml diff --git a/crates/valence_entity/README.md b/old/crates/valence_entity/README.md similarity index 100% rename from crates/valence_entity/README.md rename to old/crates/valence_entity/README.md diff --git a/crates/valence_entity/build.rs b/old/crates/valence_entity/build.rs similarity index 100% rename from crates/valence_entity/build.rs rename to old/crates/valence_entity/build.rs diff --git a/crates/valence_entity/extracted/entities.json b/old/crates/valence_entity/extracted/entities.json similarity index 100% rename from crates/valence_entity/extracted/entities.json rename to old/crates/valence_entity/extracted/entities.json diff --git a/crates/valence_entity/extracted/misc.json b/old/crates/valence_entity/extracted/misc.json similarity index 100% rename from crates/valence_entity/extracted/misc.json rename to old/crates/valence_entity/extracted/misc.json diff --git a/crates/valence_entity/src/active_status_effects.rs b/old/crates/valence_entity/src/active_status_effects.rs similarity index 100% rename from crates/valence_entity/src/active_status_effects.rs rename to old/crates/valence_entity/src/active_status_effects.rs diff --git a/crates/valence_entity/src/attributes.rs b/old/crates/valence_entity/src/attributes.rs similarity index 100% rename from crates/valence_entity/src/attributes.rs rename to old/crates/valence_entity/src/attributes.rs diff --git a/crates/valence_entity/src/flags.rs b/old/crates/valence_entity/src/flags.rs similarity index 100% rename from crates/valence_entity/src/flags.rs rename to old/crates/valence_entity/src/flags.rs diff --git a/crates/valence_entity/src/hitbox.rs b/old/crates/valence_entity/src/hitbox.rs similarity index 100% rename from crates/valence_entity/src/hitbox.rs rename to old/crates/valence_entity/src/hitbox.rs diff --git a/crates/valence_entity/src/lib.rs b/old/crates/valence_entity/src/lib.rs similarity index 100% rename from crates/valence_entity/src/lib.rs rename to old/crates/valence_entity/src/lib.rs diff --git a/crates/valence_entity/src/manager.rs b/old/crates/valence_entity/src/manager.rs similarity index 100% rename from crates/valence_entity/src/manager.rs rename to old/crates/valence_entity/src/manager.rs diff --git a/crates/valence_entity/src/query.rs b/old/crates/valence_entity/src/query.rs similarity index 100% rename from crates/valence_entity/src/query.rs rename to old/crates/valence_entity/src/query.rs diff --git a/crates/valence_entity/src/tracked_data.rs b/old/crates/valence_entity/src/tracked_data.rs similarity index 100% rename from crates/valence_entity/src/tracked_data.rs rename to old/crates/valence_entity/src/tracked_data.rs diff --git a/crates/valence_generated/Cargo.toml b/old/crates/valence_generated/Cargo.toml similarity index 100% rename from crates/valence_generated/Cargo.toml rename to old/crates/valence_generated/Cargo.toml diff --git a/crates/valence_generated/README.md b/old/crates/valence_generated/README.md similarity index 100% rename from crates/valence_generated/README.md rename to old/crates/valence_generated/README.md diff --git a/crates/valence_generated/build/attributes.rs b/old/crates/valence_generated/build/attributes.rs similarity index 100% rename from crates/valence_generated/build/attributes.rs rename to old/crates/valence_generated/build/attributes.rs diff --git a/crates/valence_generated/build/block.rs b/old/crates/valence_generated/build/block.rs similarity index 100% rename from crates/valence_generated/build/block.rs rename to old/crates/valence_generated/build/block.rs diff --git a/crates/valence_generated/build/chunk_view.rs b/old/crates/valence_generated/build/chunk_view.rs similarity index 100% rename from crates/valence_generated/build/chunk_view.rs rename to old/crates/valence_generated/build/chunk_view.rs diff --git a/crates/valence_generated/build/item.rs b/old/crates/valence_generated/build/item.rs similarity index 100% rename from crates/valence_generated/build/item.rs rename to old/crates/valence_generated/build/item.rs diff --git a/crates/valence_generated/build/main.rs b/old/crates/valence_generated/build/main.rs similarity index 100% rename from crates/valence_generated/build/main.rs rename to old/crates/valence_generated/build/main.rs diff --git a/crates/valence_generated/build/packet_id.rs b/old/crates/valence_generated/build/packet_id.rs similarity index 100% rename from crates/valence_generated/build/packet_id.rs rename to old/crates/valence_generated/build/packet_id.rs diff --git a/crates/valence_generated/build/sound.rs b/old/crates/valence_generated/build/sound.rs similarity index 100% rename from crates/valence_generated/build/sound.rs rename to old/crates/valence_generated/build/sound.rs diff --git a/crates/valence_generated/build/status_effects.rs b/old/crates/valence_generated/build/status_effects.rs similarity index 100% rename from crates/valence_generated/build/status_effects.rs rename to old/crates/valence_generated/build/status_effects.rs diff --git a/crates/valence_generated/extracted/attributes.json b/old/crates/valence_generated/extracted/attributes.json similarity index 100% rename from crates/valence_generated/extracted/attributes.json rename to old/crates/valence_generated/extracted/attributes.json diff --git a/crates/valence_generated/extracted/blocks.json b/old/crates/valence_generated/extracted/blocks.json similarity index 100% rename from crates/valence_generated/extracted/blocks.json rename to old/crates/valence_generated/extracted/blocks.json diff --git a/crates/valence_generated/extracted/effects.json b/old/crates/valence_generated/extracted/effects.json similarity index 100% rename from crates/valence_generated/extracted/effects.json rename to old/crates/valence_generated/extracted/effects.json diff --git a/crates/valence_generated/extracted/items.json b/old/crates/valence_generated/extracted/items.json similarity index 100% rename from crates/valence_generated/extracted/items.json rename to old/crates/valence_generated/extracted/items.json diff --git a/crates/valence_generated/extracted/packets.json b/old/crates/valence_generated/extracted/packets.json similarity index 100% rename from crates/valence_generated/extracted/packets.json rename to old/crates/valence_generated/extracted/packets.json diff --git a/crates/valence_generated/extracted/sounds.json b/old/crates/valence_generated/extracted/sounds.json similarity index 100% rename from crates/valence_generated/extracted/sounds.json rename to old/crates/valence_generated/extracted/sounds.json diff --git a/crates/valence_generated/src/block.rs b/old/crates/valence_generated/src/block.rs similarity index 100% rename from crates/valence_generated/src/block.rs rename to old/crates/valence_generated/src/block.rs diff --git a/crates/valence_generated/src/lib.rs b/old/crates/valence_generated/src/lib.rs similarity index 100% rename from crates/valence_generated/src/lib.rs rename to old/crates/valence_generated/src/lib.rs diff --git a/crates/valence_ident/Cargo.toml b/old/crates/valence_ident/Cargo.toml similarity index 100% rename from crates/valence_ident/Cargo.toml rename to old/crates/valence_ident/Cargo.toml diff --git a/crates/valence_ident/README.md b/old/crates/valence_ident/README.md similarity index 100% rename from crates/valence_ident/README.md rename to old/crates/valence_ident/README.md diff --git a/crates/valence_ident/src/lib.rs b/old/crates/valence_ident/src/lib.rs similarity index 100% rename from crates/valence_ident/src/lib.rs rename to old/crates/valence_ident/src/lib.rs diff --git a/crates/valence_ident_macros/Cargo.toml b/old/crates/valence_ident_macros/Cargo.toml similarity index 100% rename from crates/valence_ident_macros/Cargo.toml rename to old/crates/valence_ident_macros/Cargo.toml diff --git a/crates/valence_ident_macros/README.md b/old/crates/valence_ident_macros/README.md similarity index 100% rename from crates/valence_ident_macros/README.md rename to old/crates/valence_ident_macros/README.md diff --git a/crates/valence_ident_macros/src/lib.rs b/old/crates/valence_ident_macros/src/lib.rs similarity index 100% rename from crates/valence_ident_macros/src/lib.rs rename to old/crates/valence_ident_macros/src/lib.rs diff --git a/crates/valence_inventory/Cargo.toml b/old/crates/valence_inventory/Cargo.toml similarity index 100% rename from crates/valence_inventory/Cargo.toml rename to old/crates/valence_inventory/Cargo.toml diff --git a/crates/valence_inventory/README.md b/old/crates/valence_inventory/README.md similarity index 100% rename from crates/valence_inventory/README.md rename to old/crates/valence_inventory/README.md diff --git a/crates/valence_inventory/src/lib.rs b/old/crates/valence_inventory/src/lib.rs similarity index 100% rename from crates/valence_inventory/src/lib.rs rename to old/crates/valence_inventory/src/lib.rs diff --git a/crates/valence_inventory/src/player_inventory.rs b/old/crates/valence_inventory/src/player_inventory.rs similarity index 100% rename from crates/valence_inventory/src/player_inventory.rs rename to old/crates/valence_inventory/src/player_inventory.rs diff --git a/crates/valence_inventory/src/validate.rs b/old/crates/valence_inventory/src/validate.rs similarity index 100% rename from crates/valence_inventory/src/validate.rs rename to old/crates/valence_inventory/src/validate.rs diff --git a/crates/valence_lang/Cargo.toml b/old/crates/valence_lang/Cargo.toml similarity index 100% rename from crates/valence_lang/Cargo.toml rename to old/crates/valence_lang/Cargo.toml diff --git a/crates/valence_lang/README.md b/old/crates/valence_lang/README.md similarity index 100% rename from crates/valence_lang/README.md rename to old/crates/valence_lang/README.md diff --git a/crates/valence_lang/build.rs b/old/crates/valence_lang/build.rs similarity index 100% rename from crates/valence_lang/build.rs rename to old/crates/valence_lang/build.rs diff --git a/crates/valence_lang/extracted/translation_keys.json b/old/crates/valence_lang/extracted/translation_keys.json similarity index 100% rename from crates/valence_lang/extracted/translation_keys.json rename to old/crates/valence_lang/extracted/translation_keys.json diff --git a/crates/valence_lang/src/lib.rs b/old/crates/valence_lang/src/lib.rs similarity index 100% rename from crates/valence_lang/src/lib.rs rename to old/crates/valence_lang/src/lib.rs diff --git a/crates/valence_math/Cargo.toml b/old/crates/valence_math/Cargo.toml similarity index 100% rename from crates/valence_math/Cargo.toml rename to old/crates/valence_math/Cargo.toml diff --git a/crates/valence_math/README.md b/old/crates/valence_math/README.md similarity index 100% rename from crates/valence_math/README.md rename to old/crates/valence_math/README.md diff --git a/crates/valence_math/src/aabb.rs b/old/crates/valence_math/src/aabb.rs similarity index 100% rename from crates/valence_math/src/aabb.rs rename to old/crates/valence_math/src/aabb.rs diff --git a/crates/valence_math/src/lib.rs b/old/crates/valence_math/src/lib.rs similarity index 100% rename from crates/valence_math/src/lib.rs rename to old/crates/valence_math/src/lib.rs diff --git a/crates/valence_nbt/Cargo.toml b/old/crates/valence_nbt/Cargo.toml similarity index 100% rename from crates/valence_nbt/Cargo.toml rename to old/crates/valence_nbt/Cargo.toml diff --git a/crates/valence_nbt/README.md b/old/crates/valence_nbt/README.md similarity index 100% rename from crates/valence_nbt/README.md rename to old/crates/valence_nbt/README.md diff --git a/crates/valence_nbt/src/binary.rs b/old/crates/valence_nbt/src/binary.rs similarity index 100% rename from crates/valence_nbt/src/binary.rs rename to old/crates/valence_nbt/src/binary.rs diff --git a/crates/valence_nbt/src/binary/decode.rs b/old/crates/valence_nbt/src/binary/decode.rs similarity index 100% rename from crates/valence_nbt/src/binary/decode.rs rename to old/crates/valence_nbt/src/binary/decode.rs diff --git a/crates/valence_nbt/src/binary/encode.rs b/old/crates/valence_nbt/src/binary/encode.rs similarity index 100% rename from crates/valence_nbt/src/binary/encode.rs rename to old/crates/valence_nbt/src/binary/encode.rs diff --git a/crates/valence_nbt/src/binary/error.rs b/old/crates/valence_nbt/src/binary/error.rs similarity index 100% rename from crates/valence_nbt/src/binary/error.rs rename to old/crates/valence_nbt/src/binary/error.rs diff --git a/crates/valence_nbt/src/binary/modified_utf8.rs b/old/crates/valence_nbt/src/binary/modified_utf8.rs similarity index 100% rename from crates/valence_nbt/src/binary/modified_utf8.rs rename to old/crates/valence_nbt/src/binary/modified_utf8.rs diff --git a/crates/valence_nbt/src/binary/tests.rs b/old/crates/valence_nbt/src/binary/tests.rs similarity index 100% rename from crates/valence_nbt/src/binary/tests.rs rename to old/crates/valence_nbt/src/binary/tests.rs diff --git a/crates/valence_nbt/src/compound.rs b/old/crates/valence_nbt/src/compound.rs similarity index 100% rename from crates/valence_nbt/src/compound.rs rename to old/crates/valence_nbt/src/compound.rs diff --git a/crates/valence_nbt/src/conv.rs b/old/crates/valence_nbt/src/conv.rs similarity index 100% rename from crates/valence_nbt/src/conv.rs rename to old/crates/valence_nbt/src/conv.rs diff --git a/crates/valence_nbt/src/lib.rs b/old/crates/valence_nbt/src/lib.rs similarity index 100% rename from crates/valence_nbt/src/lib.rs rename to old/crates/valence_nbt/src/lib.rs diff --git a/crates/valence_nbt/src/list.rs b/old/crates/valence_nbt/src/list.rs similarity index 100% rename from crates/valence_nbt/src/list.rs rename to old/crates/valence_nbt/src/list.rs diff --git a/crates/valence_nbt/src/serde.rs b/old/crates/valence_nbt/src/serde.rs similarity index 100% rename from crates/valence_nbt/src/serde.rs rename to old/crates/valence_nbt/src/serde.rs diff --git a/crates/valence_nbt/src/serde/de.rs b/old/crates/valence_nbt/src/serde/de.rs similarity index 100% rename from crates/valence_nbt/src/serde/de.rs rename to old/crates/valence_nbt/src/serde/de.rs diff --git a/crates/valence_nbt/src/serde/ser.rs b/old/crates/valence_nbt/src/serde/ser.rs similarity index 100% rename from crates/valence_nbt/src/serde/ser.rs rename to old/crates/valence_nbt/src/serde/ser.rs diff --git a/crates/valence_nbt/src/serde/tests.rs b/old/crates/valence_nbt/src/serde/tests.rs similarity index 100% rename from crates/valence_nbt/src/serde/tests.rs rename to old/crates/valence_nbt/src/serde/tests.rs diff --git a/crates/valence_nbt/src/snbt.rs b/old/crates/valence_nbt/src/snbt.rs similarity index 100% rename from crates/valence_nbt/src/snbt.rs rename to old/crates/valence_nbt/src/snbt.rs diff --git a/crates/valence_nbt/src/tag.rs b/old/crates/valence_nbt/src/tag.rs similarity index 100% rename from crates/valence_nbt/src/tag.rs rename to old/crates/valence_nbt/src/tag.rs diff --git a/crates/valence_nbt/src/value.rs b/old/crates/valence_nbt/src/value.rs similarity index 100% rename from crates/valence_nbt/src/value.rs rename to old/crates/valence_nbt/src/value.rs diff --git a/crates/valence_network/Cargo.toml b/old/crates/valence_network/Cargo.toml similarity index 100% rename from crates/valence_network/Cargo.toml rename to old/crates/valence_network/Cargo.toml diff --git a/crates/valence_network/README.md b/old/crates/valence_network/README.md similarity index 100% rename from crates/valence_network/README.md rename to old/crates/valence_network/README.md diff --git a/crates/valence_network/src/byte_channel.rs b/old/crates/valence_network/src/byte_channel.rs similarity index 100% rename from crates/valence_network/src/byte_channel.rs rename to old/crates/valence_network/src/byte_channel.rs diff --git a/crates/valence_network/src/connect.rs b/old/crates/valence_network/src/connect.rs similarity index 100% rename from crates/valence_network/src/connect.rs rename to old/crates/valence_network/src/connect.rs diff --git a/crates/valence_network/src/legacy_ping.rs b/old/crates/valence_network/src/legacy_ping.rs similarity index 100% rename from crates/valence_network/src/legacy_ping.rs rename to old/crates/valence_network/src/legacy_ping.rs diff --git a/crates/valence_network/src/lib.rs b/old/crates/valence_network/src/lib.rs similarity index 100% rename from crates/valence_network/src/lib.rs rename to old/crates/valence_network/src/lib.rs diff --git a/crates/valence_network/src/packet_io.rs b/old/crates/valence_network/src/packet_io.rs similarity index 100% rename from crates/valence_network/src/packet_io.rs rename to old/crates/valence_network/src/packet_io.rs diff --git a/crates/valence_player_list/Cargo.toml b/old/crates/valence_player_list/Cargo.toml similarity index 100% rename from crates/valence_player_list/Cargo.toml rename to old/crates/valence_player_list/Cargo.toml diff --git a/crates/valence_player_list/README.md b/old/crates/valence_player_list/README.md similarity index 100% rename from crates/valence_player_list/README.md rename to old/crates/valence_player_list/README.md diff --git a/crates/valence_player_list/src/lib.rs b/old/crates/valence_player_list/src/lib.rs similarity index 100% rename from crates/valence_player_list/src/lib.rs rename to old/crates/valence_player_list/src/lib.rs diff --git a/crates/valence_protocol/Cargo.toml b/old/crates/valence_protocol/Cargo.toml similarity index 100% rename from crates/valence_protocol/Cargo.toml rename to old/crates/valence_protocol/Cargo.toml diff --git a/crates/valence_protocol/README.md b/old/crates/valence_protocol/README.md similarity index 100% rename from crates/valence_protocol/README.md rename to old/crates/valence_protocol/README.md diff --git a/crates/valence_protocol/src/array.rs b/old/crates/valence_protocol/src/array.rs similarity index 100% rename from crates/valence_protocol/src/array.rs rename to old/crates/valence_protocol/src/array.rs diff --git a/crates/valence_protocol/src/biome_pos.rs b/old/crates/valence_protocol/src/biome_pos.rs similarity index 100% rename from crates/valence_protocol/src/biome_pos.rs rename to old/crates/valence_protocol/src/biome_pos.rs diff --git a/crates/valence_protocol/src/bit_set.rs b/old/crates/valence_protocol/src/bit_set.rs similarity index 100% rename from crates/valence_protocol/src/bit_set.rs rename to old/crates/valence_protocol/src/bit_set.rs diff --git a/crates/valence_protocol/src/block_pos.rs b/old/crates/valence_protocol/src/block_pos.rs similarity index 100% rename from crates/valence_protocol/src/block_pos.rs rename to old/crates/valence_protocol/src/block_pos.rs diff --git a/crates/valence_protocol/src/bounded.rs b/old/crates/valence_protocol/src/bounded.rs similarity index 100% rename from crates/valence_protocol/src/bounded.rs rename to old/crates/valence_protocol/src/bounded.rs diff --git a/crates/valence_protocol/src/byte_angle.rs b/old/crates/valence_protocol/src/byte_angle.rs similarity index 100% rename from crates/valence_protocol/src/byte_angle.rs rename to old/crates/valence_protocol/src/byte_angle.rs diff --git a/crates/valence_protocol/src/chunk_pos.rs b/old/crates/valence_protocol/src/chunk_pos.rs similarity index 100% rename from crates/valence_protocol/src/chunk_pos.rs rename to old/crates/valence_protocol/src/chunk_pos.rs diff --git a/crates/valence_protocol/src/chunk_section_pos.rs b/old/crates/valence_protocol/src/chunk_section_pos.rs similarity index 100% rename from crates/valence_protocol/src/chunk_section_pos.rs rename to old/crates/valence_protocol/src/chunk_section_pos.rs diff --git a/crates/valence_protocol/src/decode.rs b/old/crates/valence_protocol/src/decode.rs similarity index 100% rename from crates/valence_protocol/src/decode.rs rename to old/crates/valence_protocol/src/decode.rs diff --git a/crates/valence_protocol/src/difficulty.rs b/old/crates/valence_protocol/src/difficulty.rs similarity index 100% rename from crates/valence_protocol/src/difficulty.rs rename to old/crates/valence_protocol/src/difficulty.rs diff --git a/crates/valence_protocol/src/direction.rs b/old/crates/valence_protocol/src/direction.rs similarity index 100% rename from crates/valence_protocol/src/direction.rs rename to old/crates/valence_protocol/src/direction.rs diff --git a/crates/valence_protocol/src/encode.rs b/old/crates/valence_protocol/src/encode.rs similarity index 100% rename from crates/valence_protocol/src/encode.rs rename to old/crates/valence_protocol/src/encode.rs diff --git a/crates/valence_protocol/src/game_mode.rs b/old/crates/valence_protocol/src/game_mode.rs similarity index 100% rename from crates/valence_protocol/src/game_mode.rs rename to old/crates/valence_protocol/src/game_mode.rs diff --git a/crates/valence_protocol/src/global_pos.rs b/old/crates/valence_protocol/src/global_pos.rs similarity index 100% rename from crates/valence_protocol/src/global_pos.rs rename to old/crates/valence_protocol/src/global_pos.rs diff --git a/crates/valence_protocol/src/hand.rs b/old/crates/valence_protocol/src/hand.rs similarity index 100% rename from crates/valence_protocol/src/hand.rs rename to old/crates/valence_protocol/src/hand.rs diff --git a/crates/valence_protocol/src/impls.rs b/old/crates/valence_protocol/src/impls.rs similarity index 100% rename from crates/valence_protocol/src/impls.rs rename to old/crates/valence_protocol/src/impls.rs diff --git a/crates/valence_protocol/src/impls/map.rs b/old/crates/valence_protocol/src/impls/map.rs similarity index 100% rename from crates/valence_protocol/src/impls/map.rs rename to old/crates/valence_protocol/src/impls/map.rs diff --git a/crates/valence_protocol/src/impls/math.rs b/old/crates/valence_protocol/src/impls/math.rs similarity index 100% rename from crates/valence_protocol/src/impls/math.rs rename to old/crates/valence_protocol/src/impls/math.rs diff --git a/crates/valence_protocol/src/impls/other.rs b/old/crates/valence_protocol/src/impls/other.rs similarity index 100% rename from crates/valence_protocol/src/impls/other.rs rename to old/crates/valence_protocol/src/impls/other.rs diff --git a/crates/valence_protocol/src/impls/pointer.rs b/old/crates/valence_protocol/src/impls/pointer.rs similarity index 100% rename from crates/valence_protocol/src/impls/pointer.rs rename to old/crates/valence_protocol/src/impls/pointer.rs diff --git a/crates/valence_protocol/src/impls/primitive.rs b/old/crates/valence_protocol/src/impls/primitive.rs similarity index 100% rename from crates/valence_protocol/src/impls/primitive.rs rename to old/crates/valence_protocol/src/impls/primitive.rs diff --git a/crates/valence_protocol/src/impls/sequence.rs b/old/crates/valence_protocol/src/impls/sequence.rs similarity index 100% rename from crates/valence_protocol/src/impls/sequence.rs rename to old/crates/valence_protocol/src/impls/sequence.rs diff --git a/crates/valence_protocol/src/impls/string.rs b/old/crates/valence_protocol/src/impls/string.rs similarity index 100% rename from crates/valence_protocol/src/impls/string.rs rename to old/crates/valence_protocol/src/impls/string.rs diff --git a/crates/valence_protocol/src/impls/tuple.rs b/old/crates/valence_protocol/src/impls/tuple.rs similarity index 100% rename from crates/valence_protocol/src/impls/tuple.rs rename to old/crates/valence_protocol/src/impls/tuple.rs diff --git a/crates/valence_protocol/src/item.rs b/old/crates/valence_protocol/src/item.rs similarity index 100% rename from crates/valence_protocol/src/item.rs rename to old/crates/valence_protocol/src/item.rs diff --git a/crates/valence_protocol/src/lib.rs b/old/crates/valence_protocol/src/lib.rs similarity index 100% rename from crates/valence_protocol/src/lib.rs rename to old/crates/valence_protocol/src/lib.rs diff --git a/crates/valence_protocol/src/packets.rs b/old/crates/valence_protocol/src/packets.rs similarity index 100% rename from crates/valence_protocol/src/packets.rs rename to old/crates/valence_protocol/src/packets.rs diff --git a/crates/valence_protocol/src/packets/handshaking/handshake_c2s.rs b/old/crates/valence_protocol/src/packets/handshaking/handshake_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/handshaking/handshake_c2s.rs rename to old/crates/valence_protocol/src/packets/handshaking/handshake_c2s.rs diff --git a/crates/valence_protocol/src/packets/login/login_compression_s2c.rs b/old/crates/valence_protocol/src/packets/login/login_compression_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_compression_s2c.rs rename to old/crates/valence_protocol/src/packets/login/login_compression_s2c.rs diff --git a/crates/valence_protocol/src/packets/login/login_disconnect_s2c.rs b/old/crates/valence_protocol/src/packets/login/login_disconnect_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_disconnect_s2c.rs rename to old/crates/valence_protocol/src/packets/login/login_disconnect_s2c.rs diff --git a/crates/valence_protocol/src/packets/login/login_hello_c2s.rs b/old/crates/valence_protocol/src/packets/login/login_hello_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_hello_c2s.rs rename to old/crates/valence_protocol/src/packets/login/login_hello_c2s.rs diff --git a/crates/valence_protocol/src/packets/login/login_hello_s2c.rs b/old/crates/valence_protocol/src/packets/login/login_hello_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_hello_s2c.rs rename to old/crates/valence_protocol/src/packets/login/login_hello_s2c.rs diff --git a/crates/valence_protocol/src/packets/login/login_key_c2s.rs b/old/crates/valence_protocol/src/packets/login/login_key_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_key_c2s.rs rename to old/crates/valence_protocol/src/packets/login/login_key_c2s.rs diff --git a/crates/valence_protocol/src/packets/login/login_query_request_s2c.rs b/old/crates/valence_protocol/src/packets/login/login_query_request_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_query_request_s2c.rs rename to old/crates/valence_protocol/src/packets/login/login_query_request_s2c.rs diff --git a/crates/valence_protocol/src/packets/login/login_query_response_c2s.rs b/old/crates/valence_protocol/src/packets/login/login_query_response_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_query_response_c2s.rs rename to old/crates/valence_protocol/src/packets/login/login_query_response_c2s.rs diff --git a/crates/valence_protocol/src/packets/login/login_success_s2c.rs b/old/crates/valence_protocol/src/packets/login/login_success_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/login/login_success_s2c.rs rename to old/crates/valence_protocol/src/packets/login/login_success_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/advancement_tab_c2s.rs b/old/crates/valence_protocol/src/packets/play/advancement_tab_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/advancement_tab_c2s.rs rename to old/crates/valence_protocol/src/packets/play/advancement_tab_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/advancement_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/advancement_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/advancement_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/advancement_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/block_breaking_progress_s2c.rs b/old/crates/valence_protocol/src/packets/play/block_breaking_progress_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/block_breaking_progress_s2c.rs rename to old/crates/valence_protocol/src/packets/play/block_breaking_progress_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/block_entity_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/block_entity_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/block_entity_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/block_entity_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/block_event_s2c.rs b/old/crates/valence_protocol/src/packets/play/block_event_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/block_event_s2c.rs rename to old/crates/valence_protocol/src/packets/play/block_event_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/block_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/block_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/block_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/block_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/boat_paddle_state_c2s.rs b/old/crates/valence_protocol/src/packets/play/boat_paddle_state_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/boat_paddle_state_c2s.rs rename to old/crates/valence_protocol/src/packets/play/boat_paddle_state_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/book_update_c2s.rs b/old/crates/valence_protocol/src/packets/play/book_update_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/book_update_c2s.rs rename to old/crates/valence_protocol/src/packets/play/book_update_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/boss_bar_s2c.rs b/old/crates/valence_protocol/src/packets/play/boss_bar_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/boss_bar_s2c.rs rename to old/crates/valence_protocol/src/packets/play/boss_bar_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/bundle_splitter_s2c.rs b/old/crates/valence_protocol/src/packets/play/bundle_splitter_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/bundle_splitter_s2c.rs rename to old/crates/valence_protocol/src/packets/play/bundle_splitter_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/button_click_c2s.rs b/old/crates/valence_protocol/src/packets/play/button_click_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/button_click_c2s.rs rename to old/crates/valence_protocol/src/packets/play/button_click_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/chat_message_c2s.rs b/old/crates/valence_protocol/src/packets/play/chat_message_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chat_message_c2s.rs rename to old/crates/valence_protocol/src/packets/play/chat_message_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/chat_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/chat_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chat_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chat_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chat_suggestions_s2c.rs b/old/crates/valence_protocol/src/packets/play/chat_suggestions_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chat_suggestions_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chat_suggestions_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chunk_biome_data_s2c.rs b/old/crates/valence_protocol/src/packets/play/chunk_biome_data_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chunk_biome_data_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chunk_biome_data_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chunk_data_s2c.rs b/old/crates/valence_protocol/src/packets/play/chunk_data_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chunk_data_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chunk_data_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chunk_delta_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/chunk_delta_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chunk_delta_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chunk_delta_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chunk_load_distance_s2c.rs b/old/crates/valence_protocol/src/packets/play/chunk_load_distance_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chunk_load_distance_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chunk_load_distance_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/chunk_render_distance_center_s2c.rs b/old/crates/valence_protocol/src/packets/play/chunk_render_distance_center_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/chunk_render_distance_center_s2c.rs rename to old/crates/valence_protocol/src/packets/play/chunk_render_distance_center_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/clear_title_s2c.rs b/old/crates/valence_protocol/src/packets/play/clear_title_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/clear_title_s2c.rs rename to old/crates/valence_protocol/src/packets/play/clear_title_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/click_slot_c2s.rs b/old/crates/valence_protocol/src/packets/play/click_slot_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/click_slot_c2s.rs rename to old/crates/valence_protocol/src/packets/play/click_slot_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/client_command_c2s.rs b/old/crates/valence_protocol/src/packets/play/client_command_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/client_command_c2s.rs rename to old/crates/valence_protocol/src/packets/play/client_command_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/client_settings_c2s.rs b/old/crates/valence_protocol/src/packets/play/client_settings_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/client_settings_c2s.rs rename to old/crates/valence_protocol/src/packets/play/client_settings_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/client_status_c2s.rs b/old/crates/valence_protocol/src/packets/play/client_status_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/client_status_c2s.rs rename to old/crates/valence_protocol/src/packets/play/client_status_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/close_handled_screen_c2s.rs b/old/crates/valence_protocol/src/packets/play/close_handled_screen_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/close_handled_screen_c2s.rs rename to old/crates/valence_protocol/src/packets/play/close_handled_screen_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/close_screen_s2c.rs b/old/crates/valence_protocol/src/packets/play/close_screen_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/close_screen_s2c.rs rename to old/crates/valence_protocol/src/packets/play/close_screen_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/command_execution_c2s.rs b/old/crates/valence_protocol/src/packets/play/command_execution_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/command_execution_c2s.rs rename to old/crates/valence_protocol/src/packets/play/command_execution_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/command_suggestions_s2c.rs b/old/crates/valence_protocol/src/packets/play/command_suggestions_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/command_suggestions_s2c.rs rename to old/crates/valence_protocol/src/packets/play/command_suggestions_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/command_tree_s2c.rs b/old/crates/valence_protocol/src/packets/play/command_tree_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/command_tree_s2c.rs rename to old/crates/valence_protocol/src/packets/play/command_tree_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/cooldown_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/cooldown_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/cooldown_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/cooldown_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/craft_failed_response_s2c.rs b/old/crates/valence_protocol/src/packets/play/craft_failed_response_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/craft_failed_response_s2c.rs rename to old/crates/valence_protocol/src/packets/play/craft_failed_response_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/craft_request_c2s.rs b/old/crates/valence_protocol/src/packets/play/craft_request_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/craft_request_c2s.rs rename to old/crates/valence_protocol/src/packets/play/craft_request_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/creative_inventory_action_c2s.rs b/old/crates/valence_protocol/src/packets/play/creative_inventory_action_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/creative_inventory_action_c2s.rs rename to old/crates/valence_protocol/src/packets/play/creative_inventory_action_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/custom_payload_c2s.rs b/old/crates/valence_protocol/src/packets/play/custom_payload_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/custom_payload_c2s.rs rename to old/crates/valence_protocol/src/packets/play/custom_payload_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/custom_payload_s2c.rs b/old/crates/valence_protocol/src/packets/play/custom_payload_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/custom_payload_s2c.rs rename to old/crates/valence_protocol/src/packets/play/custom_payload_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/damage_tilt_s2c.rs b/old/crates/valence_protocol/src/packets/play/damage_tilt_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/damage_tilt_s2c.rs rename to old/crates/valence_protocol/src/packets/play/damage_tilt_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/death_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/death_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/death_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/death_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/difficulty_s2c.rs b/old/crates/valence_protocol/src/packets/play/difficulty_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/difficulty_s2c.rs rename to old/crates/valence_protocol/src/packets/play/difficulty_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/disconnect_s2c.rs b/old/crates/valence_protocol/src/packets/play/disconnect_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/disconnect_s2c.rs rename to old/crates/valence_protocol/src/packets/play/disconnect_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/end_combat_s2c.rs b/old/crates/valence_protocol/src/packets/play/end_combat_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/end_combat_s2c.rs rename to old/crates/valence_protocol/src/packets/play/end_combat_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/enter_combat_s2c.rs b/old/crates/valence_protocol/src/packets/play/enter_combat_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/enter_combat_s2c.rs rename to old/crates/valence_protocol/src/packets/play/enter_combat_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entities_destroy_s2c.rs b/old/crates/valence_protocol/src/packets/play/entities_destroy_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entities_destroy_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entities_destroy_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_animation_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_animation_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_animation_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_animation_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_attach_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_attach_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_attach_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_attach_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_attributes_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_attributes_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_attributes_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_attributes_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_damage_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_damage_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_damage_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_damage_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_equipment_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_equipment_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_equipment_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_equipment_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_passengers_set_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_passengers_set_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_passengers_set_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_passengers_set_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_position_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_position_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_position_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_position_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_set_head_yaw_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_set_head_yaw_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_set_head_yaw_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_set_head_yaw_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_spawn_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_spawn_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_spawn_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_spawn_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_status_effect_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_status_effect_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_status_effect_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_status_effect_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_status_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_status_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_status_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_status_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_tracker_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_tracker_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_tracker_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_tracker_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/entity_velocity_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/entity_velocity_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/entity_velocity_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/entity_velocity_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/experience_bar_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/experience_bar_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/experience_bar_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/experience_bar_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/experience_orb_spawn_s2c.rs b/old/crates/valence_protocol/src/packets/play/experience_orb_spawn_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/experience_orb_spawn_s2c.rs rename to old/crates/valence_protocol/src/packets/play/experience_orb_spawn_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/explosion_s2c.rs b/old/crates/valence_protocol/src/packets/play/explosion_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/explosion_s2c.rs rename to old/crates/valence_protocol/src/packets/play/explosion_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/features_s2c.rs b/old/crates/valence_protocol/src/packets/play/features_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/features_s2c.rs rename to old/crates/valence_protocol/src/packets/play/features_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/full_c2s.rs b/old/crates/valence_protocol/src/packets/play/full_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/full_c2s.rs rename to old/crates/valence_protocol/src/packets/play/full_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/game_join_s2c.rs b/old/crates/valence_protocol/src/packets/play/game_join_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/game_join_s2c.rs rename to old/crates/valence_protocol/src/packets/play/game_join_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/game_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/game_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/game_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/game_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/game_state_change_s2c.rs b/old/crates/valence_protocol/src/packets/play/game_state_change_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/game_state_change_s2c.rs rename to old/crates/valence_protocol/src/packets/play/game_state_change_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/hand_swing_c2s.rs b/old/crates/valence_protocol/src/packets/play/hand_swing_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/hand_swing_c2s.rs rename to old/crates/valence_protocol/src/packets/play/hand_swing_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/health_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/health_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/health_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/health_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/inventory_s2c.rs b/old/crates/valence_protocol/src/packets/play/inventory_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/inventory_s2c.rs rename to old/crates/valence_protocol/src/packets/play/inventory_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/item_pickup_animation_s2c.rs b/old/crates/valence_protocol/src/packets/play/item_pickup_animation_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/item_pickup_animation_s2c.rs rename to old/crates/valence_protocol/src/packets/play/item_pickup_animation_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/jigsaw_generating_c2s.rs b/old/crates/valence_protocol/src/packets/play/jigsaw_generating_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/jigsaw_generating_c2s.rs rename to old/crates/valence_protocol/src/packets/play/jigsaw_generating_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/keep_alive_c2s.rs b/old/crates/valence_protocol/src/packets/play/keep_alive_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/keep_alive_c2s.rs rename to old/crates/valence_protocol/src/packets/play/keep_alive_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/keep_alive_s2c.rs b/old/crates/valence_protocol/src/packets/play/keep_alive_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/keep_alive_s2c.rs rename to old/crates/valence_protocol/src/packets/play/keep_alive_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/light_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/light_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/light_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/light_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/look_and_on_ground_c2s.rs b/old/crates/valence_protocol/src/packets/play/look_and_on_ground_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/look_and_on_ground_c2s.rs rename to old/crates/valence_protocol/src/packets/play/look_and_on_ground_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/look_at_s2c.rs b/old/crates/valence_protocol/src/packets/play/look_at_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/look_at_s2c.rs rename to old/crates/valence_protocol/src/packets/play/look_at_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/map_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/map_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/map_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/map_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/message_acknowledgment_c2s.rs b/old/crates/valence_protocol/src/packets/play/message_acknowledgment_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/message_acknowledgment_c2s.rs rename to old/crates/valence_protocol/src/packets/play/message_acknowledgment_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/move_relative_s2c.rs b/old/crates/valence_protocol/src/packets/play/move_relative_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/move_relative_s2c.rs rename to old/crates/valence_protocol/src/packets/play/move_relative_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/nbt_query_response_s2c.rs b/old/crates/valence_protocol/src/packets/play/nbt_query_response_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/nbt_query_response_s2c.rs rename to old/crates/valence_protocol/src/packets/play/nbt_query_response_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/on_ground_only_c2s.rs b/old/crates/valence_protocol/src/packets/play/on_ground_only_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/on_ground_only_c2s.rs rename to old/crates/valence_protocol/src/packets/play/on_ground_only_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/open_horse_screen_s2c.rs b/old/crates/valence_protocol/src/packets/play/open_horse_screen_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/open_horse_screen_s2c.rs rename to old/crates/valence_protocol/src/packets/play/open_horse_screen_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/open_screen_s2c.rs b/old/crates/valence_protocol/src/packets/play/open_screen_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/open_screen_s2c.rs rename to old/crates/valence_protocol/src/packets/play/open_screen_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/open_written_book_s2c.rs b/old/crates/valence_protocol/src/packets/play/open_written_book_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/open_written_book_s2c.rs rename to old/crates/valence_protocol/src/packets/play/open_written_book_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/overlay_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/overlay_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/overlay_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/overlay_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/particle_s2c.rs b/old/crates/valence_protocol/src/packets/play/particle_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/particle_s2c.rs rename to old/crates/valence_protocol/src/packets/play/particle_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/pick_from_inventory_c2s.rs b/old/crates/valence_protocol/src/packets/play/pick_from_inventory_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/pick_from_inventory_c2s.rs rename to old/crates/valence_protocol/src/packets/play/pick_from_inventory_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/play_ping_s2c.rs b/old/crates/valence_protocol/src/packets/play/play_ping_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/play_ping_s2c.rs rename to old/crates/valence_protocol/src/packets/play/play_ping_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/play_pong_c2s.rs b/old/crates/valence_protocol/src/packets/play/play_pong_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/play_pong_c2s.rs rename to old/crates/valence_protocol/src/packets/play/play_pong_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/play_sound_from_entity_s2c.rs b/old/crates/valence_protocol/src/packets/play/play_sound_from_entity_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/play_sound_from_entity_s2c.rs rename to old/crates/valence_protocol/src/packets/play/play_sound_from_entity_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/play_sound_s2c.rs b/old/crates/valence_protocol/src/packets/play/play_sound_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/play_sound_s2c.rs rename to old/crates/valence_protocol/src/packets/play/play_sound_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_abilities_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_abilities_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_abilities_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_abilities_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_action_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_action_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_action_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_action_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_action_response_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_action_response_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_action_response_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_action_response_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_input_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_input_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_input_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_input_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_interact_block_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_interact_block_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_interact_block_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_interact_block_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_interact_entity_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_interact_entity_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_interact_entity_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_interact_entity_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_interact_item_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_interact_item_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_interact_item_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_interact_item_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_list_header_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_list_header_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_list_header_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_list_header_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_list_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_list_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_list_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_list_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_position_look_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_position_look_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_position_look_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_position_look_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_remove_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_remove_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_remove_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_remove_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_respawn_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_respawn_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_respawn_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_respawn_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_session_c2s.rs b/old/crates/valence_protocol/src/packets/play/player_session_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_session_c2s.rs rename to old/crates/valence_protocol/src/packets/play/player_session_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/player_spawn_position_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_spawn_position_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_spawn_position_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_spawn_position_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/player_spawn_s2c.rs b/old/crates/valence_protocol/src/packets/play/player_spawn_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/player_spawn_s2c.rs rename to old/crates/valence_protocol/src/packets/play/player_spawn_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/position_and_on_ground_c2s.rs b/old/crates/valence_protocol/src/packets/play/position_and_on_ground_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/position_and_on_ground_c2s.rs rename to old/crates/valence_protocol/src/packets/play/position_and_on_ground_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/profileless_chat_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/profileless_chat_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/profileless_chat_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/profileless_chat_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/query_block_nbt_c2s.rs b/old/crates/valence_protocol/src/packets/play/query_block_nbt_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/query_block_nbt_c2s.rs rename to old/crates/valence_protocol/src/packets/play/query_block_nbt_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/query_entity_nbt_c2s.rs b/old/crates/valence_protocol/src/packets/play/query_entity_nbt_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/query_entity_nbt_c2s.rs rename to old/crates/valence_protocol/src/packets/play/query_entity_nbt_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/recipe_book_data_c2s.rs b/old/crates/valence_protocol/src/packets/play/recipe_book_data_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/recipe_book_data_c2s.rs rename to old/crates/valence_protocol/src/packets/play/recipe_book_data_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/recipe_category_options_c2s.rs b/old/crates/valence_protocol/src/packets/play/recipe_category_options_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/recipe_category_options_c2s.rs rename to old/crates/valence_protocol/src/packets/play/recipe_category_options_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/remove_entity_status_effect_s2c.rs b/old/crates/valence_protocol/src/packets/play/remove_entity_status_effect_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/remove_entity_status_effect_s2c.rs rename to old/crates/valence_protocol/src/packets/play/remove_entity_status_effect_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/remove_message_s2c.rs b/old/crates/valence_protocol/src/packets/play/remove_message_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/remove_message_s2c.rs rename to old/crates/valence_protocol/src/packets/play/remove_message_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/rename_item_c2s.rs b/old/crates/valence_protocol/src/packets/play/rename_item_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/rename_item_c2s.rs rename to old/crates/valence_protocol/src/packets/play/rename_item_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/request_command_completions_c2s.rs b/old/crates/valence_protocol/src/packets/play/request_command_completions_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/request_command_completions_c2s.rs rename to old/crates/valence_protocol/src/packets/play/request_command_completions_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/resource_pack_send_s2c.rs b/old/crates/valence_protocol/src/packets/play/resource_pack_send_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/resource_pack_send_s2c.rs rename to old/crates/valence_protocol/src/packets/play/resource_pack_send_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/resource_pack_status_c2s.rs b/old/crates/valence_protocol/src/packets/play/resource_pack_status_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/resource_pack_status_c2s.rs rename to old/crates/valence_protocol/src/packets/play/resource_pack_status_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/rotate_and_move_relative_s2c.rs b/old/crates/valence_protocol/src/packets/play/rotate_and_move_relative_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/rotate_and_move_relative_s2c.rs rename to old/crates/valence_protocol/src/packets/play/rotate_and_move_relative_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/rotate_s2c.rs b/old/crates/valence_protocol/src/packets/play/rotate_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/rotate_s2c.rs rename to old/crates/valence_protocol/src/packets/play/rotate_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/scoreboard_display_s2c.rs b/old/crates/valence_protocol/src/packets/play/scoreboard_display_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/scoreboard_display_s2c.rs rename to old/crates/valence_protocol/src/packets/play/scoreboard_display_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/scoreboard_objective_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/scoreboard_objective_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/scoreboard_objective_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/scoreboard_objective_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/scoreboard_player_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/scoreboard_player_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/scoreboard_player_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/scoreboard_player_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/screen_handler_property_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/screen_handler_property_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/screen_handler_property_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/screen_handler_property_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/screen_handler_slot_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/screen_handler_slot_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/screen_handler_slot_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/screen_handler_slot_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/select_advancement_tab_s2c.rs b/old/crates/valence_protocol/src/packets/play/select_advancement_tab_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/select_advancement_tab_s2c.rs rename to old/crates/valence_protocol/src/packets/play/select_advancement_tab_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/select_merchant_trade_c2s.rs b/old/crates/valence_protocol/src/packets/play/select_merchant_trade_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/select_merchant_trade_c2s.rs rename to old/crates/valence_protocol/src/packets/play/select_merchant_trade_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/server_metadata_s2c.rs b/old/crates/valence_protocol/src/packets/play/server_metadata_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/server_metadata_s2c.rs rename to old/crates/valence_protocol/src/packets/play/server_metadata_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/set_camera_entity_s2c.rs b/old/crates/valence_protocol/src/packets/play/set_camera_entity_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/set_camera_entity_s2c.rs rename to old/crates/valence_protocol/src/packets/play/set_camera_entity_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/set_trade_offers_s2c.rs b/old/crates/valence_protocol/src/packets/play/set_trade_offers_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/set_trade_offers_s2c.rs rename to old/crates/valence_protocol/src/packets/play/set_trade_offers_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/sign_editor_open_s2c.rs b/old/crates/valence_protocol/src/packets/play/sign_editor_open_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/sign_editor_open_s2c.rs rename to old/crates/valence_protocol/src/packets/play/sign_editor_open_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/simulation_distance_s2c.rs b/old/crates/valence_protocol/src/packets/play/simulation_distance_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/simulation_distance_s2c.rs rename to old/crates/valence_protocol/src/packets/play/simulation_distance_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/spectator_teleport_c2s.rs b/old/crates/valence_protocol/src/packets/play/spectator_teleport_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/spectator_teleport_c2s.rs rename to old/crates/valence_protocol/src/packets/play/spectator_teleport_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/statistics_s2c.rs b/old/crates/valence_protocol/src/packets/play/statistics_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/statistics_s2c.rs rename to old/crates/valence_protocol/src/packets/play/statistics_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/stop_sound_s2c.rs b/old/crates/valence_protocol/src/packets/play/stop_sound_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/stop_sound_s2c.rs rename to old/crates/valence_protocol/src/packets/play/stop_sound_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/subtitle_s2c.rs b/old/crates/valence_protocol/src/packets/play/subtitle_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/subtitle_s2c.rs rename to old/crates/valence_protocol/src/packets/play/subtitle_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/synchronize_recipes_s2c.rs b/old/crates/valence_protocol/src/packets/play/synchronize_recipes_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/synchronize_recipes_s2c.rs rename to old/crates/valence_protocol/src/packets/play/synchronize_recipes_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/synchronize_tags_s2c.rs b/old/crates/valence_protocol/src/packets/play/synchronize_tags_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/synchronize_tags_s2c.rs rename to old/crates/valence_protocol/src/packets/play/synchronize_tags_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/team_s2c.rs b/old/crates/valence_protocol/src/packets/play/team_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/team_s2c.rs rename to old/crates/valence_protocol/src/packets/play/team_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/teleport_confirm_c2s.rs b/old/crates/valence_protocol/src/packets/play/teleport_confirm_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/teleport_confirm_c2s.rs rename to old/crates/valence_protocol/src/packets/play/teleport_confirm_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/title_fade_s2c.rs b/old/crates/valence_protocol/src/packets/play/title_fade_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/title_fade_s2c.rs rename to old/crates/valence_protocol/src/packets/play/title_fade_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/title_s2c.rs b/old/crates/valence_protocol/src/packets/play/title_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/title_s2c.rs rename to old/crates/valence_protocol/src/packets/play/title_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/unload_chunk_s2c.rs b/old/crates/valence_protocol/src/packets/play/unload_chunk_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/unload_chunk_s2c.rs rename to old/crates/valence_protocol/src/packets/play/unload_chunk_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/unlock_recipes_s2c.rs b/old/crates/valence_protocol/src/packets/play/unlock_recipes_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/unlock_recipes_s2c.rs rename to old/crates/valence_protocol/src/packets/play/unlock_recipes_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/update_beacon_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_beacon_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_beacon_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_beacon_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_command_block_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_command_block_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_command_block_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_command_block_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_command_block_minecart_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_command_block_minecart_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_command_block_minecart_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_command_block_minecart_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_difficulty_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_difficulty_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_difficulty_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_difficulty_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_difficulty_lock_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_difficulty_lock_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_difficulty_lock_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_difficulty_lock_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_jigsaw_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_jigsaw_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_jigsaw_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_jigsaw_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_player_abilities_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_player_abilities_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_player_abilities_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_player_abilities_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_selected_slot_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_selected_slot_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_selected_slot_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_selected_slot_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_selected_slot_s2c.rs b/old/crates/valence_protocol/src/packets/play/update_selected_slot_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_selected_slot_s2c.rs rename to old/crates/valence_protocol/src/packets/play/update_selected_slot_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/update_sign_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_sign_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_sign_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_sign_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/update_structure_block_c2s.rs b/old/crates/valence_protocol/src/packets/play/update_structure_block_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/update_structure_block_c2s.rs rename to old/crates/valence_protocol/src/packets/play/update_structure_block_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/vehicle_move_c2s.rs b/old/crates/valence_protocol/src/packets/play/vehicle_move_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/vehicle_move_c2s.rs rename to old/crates/valence_protocol/src/packets/play/vehicle_move_c2s.rs diff --git a/crates/valence_protocol/src/packets/play/vehicle_move_s2c.rs b/old/crates/valence_protocol/src/packets/play/vehicle_move_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/vehicle_move_s2c.rs rename to old/crates/valence_protocol/src/packets/play/vehicle_move_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_center_changed_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_center_changed_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_center_changed_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_center_changed_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_initialize_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_initialize_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_initialize_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_initialize_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_interpolate_size_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_interpolate_size_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_interpolate_size_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_interpolate_size_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_size_changed_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_size_changed_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_size_changed_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_size_changed_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_warning_blocks_changed_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_warning_blocks_changed_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_warning_blocks_changed_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_warning_blocks_changed_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_border_warning_time_changed_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_border_warning_time_changed_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_border_warning_time_changed_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_border_warning_time_changed_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_event_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_event_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_event_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_event_s2c.rs diff --git a/crates/valence_protocol/src/packets/play/world_time_update_s2c.rs b/old/crates/valence_protocol/src/packets/play/world_time_update_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/play/world_time_update_s2c.rs rename to old/crates/valence_protocol/src/packets/play/world_time_update_s2c.rs diff --git a/crates/valence_protocol/src/packets/status.rs b/old/crates/valence_protocol/src/packets/status.rs similarity index 100% rename from crates/valence_protocol/src/packets/status.rs rename to old/crates/valence_protocol/src/packets/status.rs diff --git a/crates/valence_protocol/src/packets/status/query_ping_c2s.rs b/old/crates/valence_protocol/src/packets/status/query_ping_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/status/query_ping_c2s.rs rename to old/crates/valence_protocol/src/packets/status/query_ping_c2s.rs diff --git a/crates/valence_protocol/src/packets/status/query_pong_s2c.rs b/old/crates/valence_protocol/src/packets/status/query_pong_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/status/query_pong_s2c.rs rename to old/crates/valence_protocol/src/packets/status/query_pong_s2c.rs diff --git a/crates/valence_protocol/src/packets/status/query_request_c2s.rs b/old/crates/valence_protocol/src/packets/status/query_request_c2s.rs similarity index 100% rename from crates/valence_protocol/src/packets/status/query_request_c2s.rs rename to old/crates/valence_protocol/src/packets/status/query_request_c2s.rs diff --git a/crates/valence_protocol/src/packets/status/query_response_s2c.rs b/old/crates/valence_protocol/src/packets/status/query_response_s2c.rs similarity index 100% rename from crates/valence_protocol/src/packets/status/query_response_s2c.rs rename to old/crates/valence_protocol/src/packets/status/query_response_s2c.rs diff --git a/crates/valence_protocol/src/profile.rs b/old/crates/valence_protocol/src/profile.rs similarity index 100% rename from crates/valence_protocol/src/profile.rs rename to old/crates/valence_protocol/src/profile.rs diff --git a/crates/valence_protocol/src/raw.rs b/old/crates/valence_protocol/src/raw.rs similarity index 100% rename from crates/valence_protocol/src/raw.rs rename to old/crates/valence_protocol/src/raw.rs diff --git a/crates/valence_protocol/src/sound.rs b/old/crates/valence_protocol/src/sound.rs similarity index 100% rename from crates/valence_protocol/src/sound.rs rename to old/crates/valence_protocol/src/sound.rs diff --git a/crates/valence_protocol/src/var_int.rs b/old/crates/valence_protocol/src/var_int.rs similarity index 100% rename from crates/valence_protocol/src/var_int.rs rename to old/crates/valence_protocol/src/var_int.rs diff --git a/crates/valence_protocol/src/var_long.rs b/old/crates/valence_protocol/src/var_long.rs similarity index 100% rename from crates/valence_protocol/src/var_long.rs rename to old/crates/valence_protocol/src/var_long.rs diff --git a/crates/valence_protocol/src/velocity.rs b/old/crates/valence_protocol/src/velocity.rs similarity index 100% rename from crates/valence_protocol/src/velocity.rs rename to old/crates/valence_protocol/src/velocity.rs diff --git a/crates/valence_protocol_macros/Cargo.toml b/old/crates/valence_protocol_macros/Cargo.toml similarity index 100% rename from crates/valence_protocol_macros/Cargo.toml rename to old/crates/valence_protocol_macros/Cargo.toml diff --git a/crates/valence_protocol_macros/README.md b/old/crates/valence_protocol_macros/README.md similarity index 100% rename from crates/valence_protocol_macros/README.md rename to old/crates/valence_protocol_macros/README.md diff --git a/crates/valence_protocol_macros/src/decode.rs b/old/crates/valence_protocol_macros/src/decode.rs similarity index 100% rename from crates/valence_protocol_macros/src/decode.rs rename to old/crates/valence_protocol_macros/src/decode.rs diff --git a/crates/valence_protocol_macros/src/encode.rs b/old/crates/valence_protocol_macros/src/encode.rs similarity index 100% rename from crates/valence_protocol_macros/src/encode.rs rename to old/crates/valence_protocol_macros/src/encode.rs diff --git a/crates/valence_protocol_macros/src/lib.rs b/old/crates/valence_protocol_macros/src/lib.rs similarity index 100% rename from crates/valence_protocol_macros/src/lib.rs rename to old/crates/valence_protocol_macros/src/lib.rs diff --git a/crates/valence_protocol_macros/src/packet.rs b/old/crates/valence_protocol_macros/src/packet.rs similarity index 100% rename from crates/valence_protocol_macros/src/packet.rs rename to old/crates/valence_protocol_macros/src/packet.rs diff --git a/crates/valence_registry/Cargo.toml b/old/crates/valence_registry/Cargo.toml similarity index 100% rename from crates/valence_registry/Cargo.toml rename to old/crates/valence_registry/Cargo.toml diff --git a/crates/valence_registry/README.md b/old/crates/valence_registry/README.md similarity index 100% rename from crates/valence_registry/README.md rename to old/crates/valence_registry/README.md diff --git a/crates/valence_registry/extracted/registry_codec.dat b/old/crates/valence_registry/extracted/registry_codec.dat similarity index 100% rename from crates/valence_registry/extracted/registry_codec.dat rename to old/crates/valence_registry/extracted/registry_codec.dat diff --git a/crates/valence_registry/extracted/tags.json b/old/crates/valence_registry/extracted/tags.json similarity index 100% rename from crates/valence_registry/extracted/tags.json rename to old/crates/valence_registry/extracted/tags.json diff --git a/crates/valence_registry/src/biome.rs b/old/crates/valence_registry/src/biome.rs similarity index 100% rename from crates/valence_registry/src/biome.rs rename to old/crates/valence_registry/src/biome.rs diff --git a/crates/valence_registry/src/codec.rs b/old/crates/valence_registry/src/codec.rs similarity index 100% rename from crates/valence_registry/src/codec.rs rename to old/crates/valence_registry/src/codec.rs diff --git a/crates/valence_registry/src/dimension_type.rs b/old/crates/valence_registry/src/dimension_type.rs similarity index 100% rename from crates/valence_registry/src/dimension_type.rs rename to old/crates/valence_registry/src/dimension_type.rs diff --git a/crates/valence_registry/src/lib.rs b/old/crates/valence_registry/src/lib.rs similarity index 100% rename from crates/valence_registry/src/lib.rs rename to old/crates/valence_registry/src/lib.rs diff --git a/crates/valence_registry/src/tags.rs b/old/crates/valence_registry/src/tags.rs similarity index 100% rename from crates/valence_registry/src/tags.rs rename to old/crates/valence_registry/src/tags.rs diff --git a/crates/valence_scoreboard/Cargo.toml b/old/crates/valence_scoreboard/Cargo.toml similarity index 100% rename from crates/valence_scoreboard/Cargo.toml rename to old/crates/valence_scoreboard/Cargo.toml diff --git a/crates/valence_scoreboard/README.md b/old/crates/valence_scoreboard/README.md similarity index 100% rename from crates/valence_scoreboard/README.md rename to old/crates/valence_scoreboard/README.md diff --git a/crates/valence_scoreboard/src/components.rs b/old/crates/valence_scoreboard/src/components.rs similarity index 100% rename from crates/valence_scoreboard/src/components.rs rename to old/crates/valence_scoreboard/src/components.rs diff --git a/crates/valence_scoreboard/src/lib.rs b/old/crates/valence_scoreboard/src/lib.rs similarity index 100% rename from crates/valence_scoreboard/src/lib.rs rename to old/crates/valence_scoreboard/src/lib.rs diff --git a/crates/valence_server/Cargo.toml b/old/crates/valence_server/Cargo.toml similarity index 100% rename from crates/valence_server/Cargo.toml rename to old/crates/valence_server/Cargo.toml diff --git a/crates/valence_server/README.md b/old/crates/valence_server/README.md similarity index 100% rename from crates/valence_server/README.md rename to old/crates/valence_server/README.md diff --git a/crates/valence_server/src/abilities.rs b/old/crates/valence_server/src/abilities.rs similarity index 100% rename from crates/valence_server/src/abilities.rs rename to old/crates/valence_server/src/abilities.rs diff --git a/crates/valence_server/src/action.rs b/old/crates/valence_server/src/action.rs similarity index 100% rename from crates/valence_server/src/action.rs rename to old/crates/valence_server/src/action.rs diff --git a/crates/valence_server/src/brand.rs b/old/crates/valence_server/src/brand.rs similarity index 100% rename from crates/valence_server/src/brand.rs rename to old/crates/valence_server/src/brand.rs diff --git a/crates/valence_server/src/chunk_view.rs b/old/crates/valence_server/src/chunk_view.rs similarity index 100% rename from crates/valence_server/src/chunk_view.rs rename to old/crates/valence_server/src/chunk_view.rs diff --git a/crates/valence_server/src/client.rs b/old/crates/valence_server/src/client.rs similarity index 100% rename from crates/valence_server/src/client.rs rename to old/crates/valence_server/src/client.rs diff --git a/crates/valence_server/src/client_command.rs b/old/crates/valence_server/src/client_command.rs similarity index 100% rename from crates/valence_server/src/client_command.rs rename to old/crates/valence_server/src/client_command.rs diff --git a/crates/valence_server/src/client_settings.rs b/old/crates/valence_server/src/client_settings.rs similarity index 100% rename from crates/valence_server/src/client_settings.rs rename to old/crates/valence_server/src/client_settings.rs diff --git a/crates/valence_server/src/custom_payload.rs b/old/crates/valence_server/src/custom_payload.rs similarity index 100% rename from crates/valence_server/src/custom_payload.rs rename to old/crates/valence_server/src/custom_payload.rs diff --git a/crates/valence_server/src/event_loop.rs b/old/crates/valence_server/src/event_loop.rs similarity index 100% rename from crates/valence_server/src/event_loop.rs rename to old/crates/valence_server/src/event_loop.rs diff --git a/crates/valence_server/src/hand_swing.rs b/old/crates/valence_server/src/hand_swing.rs similarity index 100% rename from crates/valence_server/src/hand_swing.rs rename to old/crates/valence_server/src/hand_swing.rs diff --git a/crates/valence_server/src/interact_block.rs b/old/crates/valence_server/src/interact_block.rs similarity index 100% rename from crates/valence_server/src/interact_block.rs rename to old/crates/valence_server/src/interact_block.rs diff --git a/crates/valence_server/src/interact_entity.rs b/old/crates/valence_server/src/interact_entity.rs similarity index 100% rename from crates/valence_server/src/interact_entity.rs rename to old/crates/valence_server/src/interact_entity.rs diff --git a/crates/valence_server/src/interact_item.rs b/old/crates/valence_server/src/interact_item.rs similarity index 100% rename from crates/valence_server/src/interact_item.rs rename to old/crates/valence_server/src/interact_item.rs diff --git a/crates/valence_server/src/keepalive.rs b/old/crates/valence_server/src/keepalive.rs similarity index 100% rename from crates/valence_server/src/keepalive.rs rename to old/crates/valence_server/src/keepalive.rs diff --git a/crates/valence_server/src/layer.rs b/old/crates/valence_server/src/layer.rs similarity index 100% rename from crates/valence_server/src/layer.rs rename to old/crates/valence_server/src/layer.rs diff --git a/crates/valence_server/src/layer/bvh.rs b/old/crates/valence_server/src/layer/bvh.rs similarity index 100% rename from crates/valence_server/src/layer/bvh.rs rename to old/crates/valence_server/src/layer/bvh.rs diff --git a/crates/valence_server/src/layer/chunk.rs b/old/crates/valence_server/src/layer/chunk.rs similarity index 100% rename from crates/valence_server/src/layer/chunk.rs rename to old/crates/valence_server/src/layer/chunk.rs diff --git a/crates/valence_server/src/layer/chunk/chunk.rs b/old/crates/valence_server/src/layer/chunk/chunk.rs similarity index 100% rename from crates/valence_server/src/layer/chunk/chunk.rs rename to old/crates/valence_server/src/layer/chunk/chunk.rs diff --git a/crates/valence_server/src/layer/chunk/loaded.rs b/old/crates/valence_server/src/layer/chunk/loaded.rs similarity index 100% rename from crates/valence_server/src/layer/chunk/loaded.rs rename to old/crates/valence_server/src/layer/chunk/loaded.rs diff --git a/crates/valence_server/src/layer/chunk/paletted_container.rs b/old/crates/valence_server/src/layer/chunk/paletted_container.rs similarity index 100% rename from crates/valence_server/src/layer/chunk/paletted_container.rs rename to old/crates/valence_server/src/layer/chunk/paletted_container.rs diff --git a/crates/valence_server/src/layer/chunk/unloaded.rs b/old/crates/valence_server/src/layer/chunk/unloaded.rs similarity index 100% rename from crates/valence_server/src/layer/chunk/unloaded.rs rename to old/crates/valence_server/src/layer/chunk/unloaded.rs diff --git a/crates/valence_server/src/layer/entity.rs b/old/crates/valence_server/src/layer/entity.rs similarity index 100% rename from crates/valence_server/src/layer/entity.rs rename to old/crates/valence_server/src/layer/entity.rs diff --git a/crates/valence_server/src/layer/message.rs b/old/crates/valence_server/src/layer/message.rs similarity index 100% rename from crates/valence_server/src/layer/message.rs rename to old/crates/valence_server/src/layer/message.rs diff --git a/crates/valence_server/src/lib.rs b/old/crates/valence_server/src/lib.rs similarity index 100% rename from crates/valence_server/src/lib.rs rename to old/crates/valence_server/src/lib.rs diff --git a/crates/valence_server/src/message.rs b/old/crates/valence_server/src/message.rs similarity index 100% rename from crates/valence_server/src/message.rs rename to old/crates/valence_server/src/message.rs diff --git a/crates/valence_server/src/movement.rs b/old/crates/valence_server/src/movement.rs similarity index 100% rename from crates/valence_server/src/movement.rs rename to old/crates/valence_server/src/movement.rs diff --git a/crates/valence_server/src/op_level.rs b/old/crates/valence_server/src/op_level.rs similarity index 100% rename from crates/valence_server/src/op_level.rs rename to old/crates/valence_server/src/op_level.rs diff --git a/crates/valence_server/src/resource_pack.rs b/old/crates/valence_server/src/resource_pack.rs similarity index 100% rename from crates/valence_server/src/resource_pack.rs rename to old/crates/valence_server/src/resource_pack.rs diff --git a/crates/valence_server/src/spawn.rs b/old/crates/valence_server/src/spawn.rs similarity index 100% rename from crates/valence_server/src/spawn.rs rename to old/crates/valence_server/src/spawn.rs diff --git a/crates/valence_server/src/status.rs b/old/crates/valence_server/src/status.rs similarity index 100% rename from crates/valence_server/src/status.rs rename to old/crates/valence_server/src/status.rs diff --git a/crates/valence_server/src/status_effect.rs b/old/crates/valence_server/src/status_effect.rs similarity index 100% rename from crates/valence_server/src/status_effect.rs rename to old/crates/valence_server/src/status_effect.rs diff --git a/crates/valence_server/src/teleport.rs b/old/crates/valence_server/src/teleport.rs similarity index 100% rename from crates/valence_server/src/teleport.rs rename to old/crates/valence_server/src/teleport.rs diff --git a/crates/valence_server/src/title.rs b/old/crates/valence_server/src/title.rs similarity index 100% rename from crates/valence_server/src/title.rs rename to old/crates/valence_server/src/title.rs diff --git a/crates/valence_server_common/Cargo.toml b/old/crates/valence_server_common/Cargo.toml similarity index 100% rename from crates/valence_server_common/Cargo.toml rename to old/crates/valence_server_common/Cargo.toml diff --git a/crates/valence_server_common/README.md b/old/crates/valence_server_common/README.md similarity index 100% rename from crates/valence_server_common/README.md rename to old/crates/valence_server_common/README.md diff --git a/crates/valence_server_common/src/despawn.rs b/old/crates/valence_server_common/src/despawn.rs similarity index 100% rename from crates/valence_server_common/src/despawn.rs rename to old/crates/valence_server_common/src/despawn.rs diff --git a/crates/valence_server_common/src/lib.rs b/old/crates/valence_server_common/src/lib.rs similarity index 100% rename from crates/valence_server_common/src/lib.rs rename to old/crates/valence_server_common/src/lib.rs diff --git a/crates/valence_server_common/src/uuid.rs b/old/crates/valence_server_common/src/uuid.rs similarity index 100% rename from crates/valence_server_common/src/uuid.rs rename to old/crates/valence_server_common/src/uuid.rs diff --git a/crates/valence_spatial/Cargo.toml b/old/crates/valence_spatial/Cargo.toml similarity index 100% rename from crates/valence_spatial/Cargo.toml rename to old/crates/valence_spatial/Cargo.toml diff --git a/crates/valence_spatial/README.md b/old/crates/valence_spatial/README.md similarity index 100% rename from crates/valence_spatial/README.md rename to old/crates/valence_spatial/README.md diff --git a/crates/valence_spatial/src/bvh.rs b/old/crates/valence_spatial/src/bvh.rs similarity index 100% rename from crates/valence_spatial/src/bvh.rs rename to old/crates/valence_spatial/src/bvh.rs diff --git a/crates/valence_spatial/src/lib.rs b/old/crates/valence_spatial/src/lib.rs similarity index 100% rename from crates/valence_spatial/src/lib.rs rename to old/crates/valence_spatial/src/lib.rs diff --git a/crates/valence_text/Cargo.toml b/old/crates/valence_text/Cargo.toml similarity index 100% rename from crates/valence_text/Cargo.toml rename to old/crates/valence_text/Cargo.toml diff --git a/crates/valence_text/README.md b/old/crates/valence_text/README.md similarity index 100% rename from crates/valence_text/README.md rename to old/crates/valence_text/README.md diff --git a/crates/valence_text/src/color.rs b/old/crates/valence_text/src/color.rs similarity index 100% rename from crates/valence_text/src/color.rs rename to old/crates/valence_text/src/color.rs diff --git a/crates/valence_text/src/into_text.rs b/old/crates/valence_text/src/into_text.rs similarity index 100% rename from crates/valence_text/src/into_text.rs rename to old/crates/valence_text/src/into_text.rs diff --git a/crates/valence_text/src/lib.rs b/old/crates/valence_text/src/lib.rs similarity index 100% rename from crates/valence_text/src/lib.rs rename to old/crates/valence_text/src/lib.rs diff --git a/crates/valence_text/src/tests.rs b/old/crates/valence_text/src/tests.rs similarity index 100% rename from crates/valence_text/src/tests.rs rename to old/crates/valence_text/src/tests.rs diff --git a/crates/valence_weather/Cargo.toml b/old/crates/valence_weather/Cargo.toml similarity index 100% rename from crates/valence_weather/Cargo.toml rename to old/crates/valence_weather/Cargo.toml diff --git a/crates/valence_weather/README.md b/old/crates/valence_weather/README.md similarity index 100% rename from crates/valence_weather/README.md rename to old/crates/valence_weather/README.md diff --git a/crates/valence_weather/src/lib.rs b/old/crates/valence_weather/src/lib.rs similarity index 100% rename from crates/valence_weather/src/lib.rs rename to old/crates/valence_weather/src/lib.rs diff --git a/crates/valence_weather/src/packet.rs b/old/crates/valence_weather/src/packet.rs similarity index 100% rename from crates/valence_weather/src/packet.rs rename to old/crates/valence_weather/src/packet.rs diff --git a/crates/valence_world_border/Cargo.toml b/old/crates/valence_world_border/Cargo.toml similarity index 100% rename from crates/valence_world_border/Cargo.toml rename to old/crates/valence_world_border/Cargo.toml diff --git a/crates/valence_world_border/README.md b/old/crates/valence_world_border/README.md similarity index 100% rename from crates/valence_world_border/README.md rename to old/crates/valence_world_border/README.md diff --git a/crates/valence_world_border/src/lib.rs b/old/crates/valence_world_border/src/lib.rs similarity index 100% rename from crates/valence_world_border/src/lib.rs rename to old/crates/valence_world_border/src/lib.rs diff --git a/examples/advancement.rs b/old/examples/advancement.rs similarity index 100% rename from examples/advancement.rs rename to old/examples/advancement.rs diff --git a/examples/anvil_loading.rs b/old/examples/anvil_loading.rs similarity index 100% rename from examples/anvil_loading.rs rename to old/examples/anvil_loading.rs diff --git a/examples/bench_players.rs b/old/examples/bench_players.rs similarity index 100% rename from examples/bench_players.rs rename to old/examples/bench_players.rs diff --git a/examples/biomes.rs b/old/examples/biomes.rs similarity index 100% rename from examples/biomes.rs rename to old/examples/biomes.rs diff --git a/examples/block_entities.rs b/old/examples/block_entities.rs similarity index 100% rename from examples/block_entities.rs rename to old/examples/block_entities.rs diff --git a/examples/boss_bar.rs b/old/examples/boss_bar.rs similarity index 100% rename from examples/boss_bar.rs rename to old/examples/boss_bar.rs diff --git a/examples/building.rs b/old/examples/building.rs similarity index 100% rename from examples/building.rs rename to old/examples/building.rs diff --git a/examples/chest.rs b/old/examples/chest.rs similarity index 100% rename from examples/chest.rs rename to old/examples/chest.rs diff --git a/examples/combat.rs b/old/examples/combat.rs similarity index 100% rename from examples/combat.rs rename to old/examples/combat.rs diff --git a/examples/command.rs b/old/examples/command.rs similarity index 100% rename from examples/command.rs rename to old/examples/command.rs diff --git a/examples/cow_sphere.rs b/old/examples/cow_sphere.rs similarity index 100% rename from examples/cow_sphere.rs rename to old/examples/cow_sphere.rs diff --git a/examples/ctf.rs b/old/examples/ctf.rs similarity index 100% rename from examples/ctf.rs rename to old/examples/ctf.rs diff --git a/examples/custom_npc.rs b/old/examples/custom_npc.rs similarity index 100% rename from examples/custom_npc.rs rename to old/examples/custom_npc.rs diff --git a/examples/death.rs b/old/examples/death.rs similarity index 100% rename from examples/death.rs rename to old/examples/death.rs diff --git a/examples/entity_hitbox.rs b/old/examples/entity_hitbox.rs similarity index 100% rename from examples/entity_hitbox.rs rename to old/examples/entity_hitbox.rs diff --git a/examples/game_of_life.rs b/old/examples/game_of_life.rs similarity index 100% rename from examples/game_of_life.rs rename to old/examples/game_of_life.rs diff --git a/examples/parkour.rs b/old/examples/parkour.rs similarity index 100% rename from examples/parkour.rs rename to old/examples/parkour.rs diff --git a/examples/particles.rs b/old/examples/particles.rs similarity index 100% rename from examples/particles.rs rename to old/examples/particles.rs diff --git a/examples/player_list.rs b/old/examples/player_list.rs similarity index 100% rename from examples/player_list.rs rename to old/examples/player_list.rs diff --git a/examples/potions.rs b/old/examples/potions.rs similarity index 100% rename from examples/potions.rs rename to old/examples/potions.rs diff --git a/examples/resource_pack.rs b/old/examples/resource_pack.rs similarity index 100% rename from examples/resource_pack.rs rename to old/examples/resource_pack.rs diff --git a/examples/server_list_ping.rs b/old/examples/server_list_ping.rs similarity index 100% rename from examples/server_list_ping.rs rename to old/examples/server_list_ping.rs diff --git a/examples/terrain.rs b/old/examples/terrain.rs similarity index 100% rename from examples/terrain.rs rename to old/examples/terrain.rs diff --git a/examples/text.rs b/old/examples/text.rs similarity index 100% rename from examples/text.rs rename to old/examples/text.rs diff --git a/examples/weather.rs b/old/examples/weather.rs similarity index 100% rename from examples/weather.rs rename to old/examples/weather.rs diff --git a/examples/world_border.rs b/old/examples/world_border.rs similarity index 100% rename from examples/world_border.rs rename to old/examples/world_border.rs diff --git a/extractor/README.md b/old/extractor/README.md similarity index 100% rename from extractor/README.md rename to old/extractor/README.md diff --git a/extractor/build.gradle b/old/extractor/build.gradle similarity index 100% rename from extractor/build.gradle rename to old/extractor/build.gradle diff --git a/extractor/copy_extractor_output.sh b/old/extractor/copy_extractor_output.sh similarity index 100% rename from extractor/copy_extractor_output.sh rename to old/extractor/copy_extractor_output.sh diff --git a/extractor/gradle.properties b/old/extractor/gradle.properties similarity index 100% rename from extractor/gradle.properties rename to old/extractor/gradle.properties diff --git a/extractor/gradle/wrapper/gradle-wrapper.jar b/old/extractor/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from extractor/gradle/wrapper/gradle-wrapper.jar rename to old/extractor/gradle/wrapper/gradle-wrapper.jar diff --git a/extractor/gradle/wrapper/gradle-wrapper.properties b/old/extractor/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from extractor/gradle/wrapper/gradle-wrapper.properties rename to old/extractor/gradle/wrapper/gradle-wrapper.properties diff --git a/extractor/gradlew b/old/extractor/gradlew similarity index 100% rename from extractor/gradlew rename to old/extractor/gradlew diff --git a/extractor/gradlew.bat b/old/extractor/gradlew.bat similarity index 100% rename from extractor/gradlew.bat rename to old/extractor/gradlew.bat diff --git a/extractor/settings.gradle b/old/extractor/settings.gradle similarity index 100% rename from extractor/settings.gradle rename to old/extractor/settings.gradle diff --git a/extractor/src/main/java/rs/valence/extractor/ClassComparator.java b/old/extractor/src/main/java/rs/valence/extractor/ClassComparator.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/ClassComparator.java rename to old/extractor/src/main/java/rs/valence/extractor/ClassComparator.java diff --git a/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java b/old/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java rename to old/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java diff --git a/extractor/src/main/java/rs/valence/extractor/DummyWorld.java b/old/extractor/src/main/java/rs/valence/extractor/DummyWorld.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/DummyWorld.java rename to old/extractor/src/main/java/rs/valence/extractor/DummyWorld.java diff --git a/extractor/src/main/java/rs/valence/extractor/Main.java b/old/extractor/src/main/java/rs/valence/extractor/Main.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/Main.java rename to old/extractor/src/main/java/rs/valence/extractor/Main.java diff --git a/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java b/old/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java rename to old/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java diff --git a/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java b/old/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/ValenceUtils.java rename to old/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Codec.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Effects.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Entities.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Items.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Items.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Items.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Items.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Misc.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Packets.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/Tags.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java b/old/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java rename to old/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java diff --git a/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java b/old/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java similarity index 100% rename from extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java rename to old/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java diff --git a/extractor/src/main/resources/extractor.mixins.json b/old/extractor/src/main/resources/extractor.mixins.json similarity index 100% rename from extractor/src/main/resources/extractor.mixins.json rename to old/extractor/src/main/resources/extractor.mixins.json diff --git a/extractor/src/main/resources/fabric.mod.json b/old/extractor/src/main/resources/fabric.mod.json similarity index 100% rename from extractor/src/main/resources/fabric.mod.json rename to old/extractor/src/main/resources/fabric.mod.json diff --git a/rustfmt.toml b/old/rustfmt.toml similarity index 100% rename from rustfmt.toml rename to old/rustfmt.toml diff --git a/src/lib.rs b/old/src/lib.rs similarity index 100% rename from src/lib.rs rename to old/src/lib.rs diff --git a/src/testing.rs b/old/src/testing.rs similarity index 100% rename from src/testing.rs rename to old/src/testing.rs diff --git a/src/tests.rs b/old/src/tests.rs similarity index 100% rename from src/tests.rs rename to old/src/tests.rs diff --git a/src/tests/boss_bar.rs b/old/src/tests/boss_bar.rs similarity index 100% rename from src/tests/boss_bar.rs rename to old/src/tests/boss_bar.rs diff --git a/src/tests/client.rs b/old/src/tests/client.rs similarity index 100% rename from src/tests/client.rs rename to old/src/tests/client.rs diff --git a/src/tests/example.rs b/old/src/tests/example.rs similarity index 100% rename from src/tests/example.rs rename to old/src/tests/example.rs diff --git a/src/tests/hunger.rs b/old/src/tests/hunger.rs similarity index 100% rename from src/tests/hunger.rs rename to old/src/tests/hunger.rs diff --git a/src/tests/inventory.rs b/old/src/tests/inventory.rs similarity index 100% rename from src/tests/inventory.rs rename to old/src/tests/inventory.rs diff --git a/src/tests/layer.rs b/old/src/tests/layer.rs similarity index 100% rename from src/tests/layer.rs rename to old/src/tests/layer.rs diff --git a/src/tests/player_list.rs b/old/src/tests/player_list.rs similarity index 100% rename from src/tests/player_list.rs rename to old/src/tests/player_list.rs diff --git a/src/tests/potions.rs b/old/src/tests/potions.rs similarity index 100% rename from src/tests/potions.rs rename to old/src/tests/potions.rs diff --git a/src/tests/scoreboard.rs b/old/src/tests/scoreboard.rs similarity index 100% rename from src/tests/scoreboard.rs rename to old/src/tests/scoreboard.rs diff --git a/src/tests/weather.rs b/old/src/tests/weather.rs similarity index 100% rename from src/tests/weather.rs rename to old/src/tests/weather.rs diff --git a/src/tests/world_border.rs b/old/src/tests/world_border.rs similarity index 100% rename from src/tests/world_border.rs rename to old/src/tests/world_border.rs diff --git a/tools/dump_schedule/Cargo.toml b/old/tools/dump_schedule/Cargo.toml similarity index 100% rename from tools/dump_schedule/Cargo.toml rename to old/tools/dump_schedule/Cargo.toml diff --git a/tools/dump_schedule/README.md b/old/tools/dump_schedule/README.md similarity index 100% rename from tools/dump_schedule/README.md rename to old/tools/dump_schedule/README.md diff --git a/tools/dump_schedule/src/main.rs b/old/tools/dump_schedule/src/main.rs similarity index 100% rename from tools/dump_schedule/src/main.rs rename to old/tools/dump_schedule/src/main.rs diff --git a/tools/packet_inspector/Cargo.toml b/old/tools/packet_inspector/Cargo.toml similarity index 100% rename from tools/packet_inspector/Cargo.toml rename to old/tools/packet_inspector/Cargo.toml diff --git a/tools/packet_inspector/README.md b/old/tools/packet_inspector/README.md similarity index 100% rename from tools/packet_inspector/README.md rename to old/tools/packet_inspector/README.md diff --git a/tools/packet_inspector/build.rs b/old/tools/packet_inspector/build.rs similarity index 100% rename from tools/packet_inspector/build.rs rename to old/tools/packet_inspector/build.rs diff --git a/tools/packet_inspector/extracted/packets.json b/old/tools/packet_inspector/extracted/packets.json similarity index 100% rename from tools/packet_inspector/extracted/packets.json rename to old/tools/packet_inspector/extracted/packets.json diff --git a/tools/packet_inspector/src/app.rs b/old/tools/packet_inspector/src/app.rs similarity index 100% rename from tools/packet_inspector/src/app.rs rename to old/tools/packet_inspector/src/app.rs diff --git a/tools/packet_inspector/src/app/connection.rs b/old/tools/packet_inspector/src/app/connection.rs similarity index 100% rename from tools/packet_inspector/src/app/connection.rs rename to old/tools/packet_inspector/src/app/connection.rs diff --git a/tools/packet_inspector/src/app/filter.rs b/old/tools/packet_inspector/src/app/filter.rs similarity index 100% rename from tools/packet_inspector/src/app/filter.rs rename to old/tools/packet_inspector/src/app/filter.rs diff --git a/tools/packet_inspector/src/app/hex_viewer.rs b/old/tools/packet_inspector/src/app/hex_viewer.rs similarity index 100% rename from tools/packet_inspector/src/app/hex_viewer.rs rename to old/tools/packet_inspector/src/app/hex_viewer.rs diff --git a/tools/packet_inspector/src/app/packet_list.rs b/old/tools/packet_inspector/src/app/packet_list.rs similarity index 100% rename from tools/packet_inspector/src/app/packet_list.rs rename to old/tools/packet_inspector/src/app/packet_list.rs diff --git a/tools/packet_inspector/src/app/text_viewer.rs b/old/tools/packet_inspector/src/app/text_viewer.rs similarity index 100% rename from tools/packet_inspector/src/app/text_viewer.rs rename to old/tools/packet_inspector/src/app/text_viewer.rs diff --git a/tools/packet_inspector/src/lib.rs b/old/tools/packet_inspector/src/lib.rs similarity index 100% rename from tools/packet_inspector/src/lib.rs rename to old/tools/packet_inspector/src/lib.rs diff --git a/tools/packet_inspector/src/main.rs b/old/tools/packet_inspector/src/main.rs similarity index 100% rename from tools/packet_inspector/src/main.rs rename to old/tools/packet_inspector/src/main.rs diff --git a/tools/packet_inspector/src/main_cli.rs b/old/tools/packet_inspector/src/main_cli.rs similarity index 100% rename from tools/packet_inspector/src/main_cli.rs rename to old/tools/packet_inspector/src/main_cli.rs diff --git a/tools/packet_inspector/src/packet_io.rs b/old/tools/packet_inspector/src/packet_io.rs similarity index 100% rename from tools/packet_inspector/src/packet_io.rs rename to old/tools/packet_inspector/src/packet_io.rs diff --git a/tools/packet_inspector/src/packet_registry.rs b/old/tools/packet_inspector/src/packet_registry.rs similarity index 100% rename from tools/packet_inspector/src/packet_registry.rs rename to old/tools/packet_inspector/src/packet_registry.rs diff --git a/tools/packet_inspector/src/shared_state.rs b/old/tools/packet_inspector/src/shared_state.rs similarity index 100% rename from tools/packet_inspector/src/shared_state.rs rename to old/tools/packet_inspector/src/shared_state.rs diff --git a/tools/packet_inspector/src/tri_checkbox.rs b/old/tools/packet_inspector/src/tri_checkbox.rs similarity index 100% rename from tools/packet_inspector/src/tri_checkbox.rs rename to old/tools/packet_inspector/src/tri_checkbox.rs diff --git a/tools/playground/Cargo.toml b/old/tools/playground/Cargo.toml similarity index 100% rename from tools/playground/Cargo.toml rename to old/tools/playground/Cargo.toml diff --git a/tools/playground/README.md b/old/tools/playground/README.md similarity index 100% rename from tools/playground/README.md rename to old/tools/playground/README.md diff --git a/tools/playground/build.rs b/old/tools/playground/build.rs similarity index 100% rename from tools/playground/build.rs rename to old/tools/playground/build.rs diff --git a/tools/playground/src/.gitignore b/old/tools/playground/src/.gitignore similarity index 100% rename from tools/playground/src/.gitignore rename to old/tools/playground/src/.gitignore diff --git a/tools/playground/src/extras.rs b/old/tools/playground/src/extras.rs similarity index 100% rename from tools/playground/src/extras.rs rename to old/tools/playground/src/extras.rs diff --git a/tools/playground/src/main.rs b/old/tools/playground/src/main.rs similarity index 100% rename from tools/playground/src/main.rs rename to old/tools/playground/src/main.rs diff --git a/tools/playground/src/playground.template.rs b/old/tools/playground/src/playground.template.rs similarity index 100% rename from tools/playground/src/playground.template.rs rename to old/tools/playground/src/playground.template.rs diff --git a/tools/stresser/Cargo.toml b/old/tools/stresser/Cargo.toml similarity index 100% rename from tools/stresser/Cargo.toml rename to old/tools/stresser/Cargo.toml diff --git a/tools/stresser/README.md b/old/tools/stresser/README.md similarity index 100% rename from tools/stresser/README.md rename to old/tools/stresser/README.md diff --git a/tools/stresser/src/args.rs b/old/tools/stresser/src/args.rs similarity index 100% rename from tools/stresser/src/args.rs rename to old/tools/stresser/src/args.rs diff --git a/tools/stresser/src/main.rs b/old/tools/stresser/src/main.rs similarity index 100% rename from tools/stresser/src/main.rs rename to old/tools/stresser/src/main.rs diff --git a/tools/stresser/src/stresser.rs b/old/tools/stresser/src/stresser.rs similarity index 100% rename from tools/stresser/src/stresser.rs rename to old/tools/stresser/src/stresser.rs diff --git a/typos.toml b/old/typos.toml similarity index 100% rename from typos.toml rename to old/typos.toml diff --git a/website/.gitignore b/old/website/.gitignore similarity index 100% rename from website/.gitignore rename to old/website/.gitignore diff --git a/website/README.md b/old/website/README.md similarity index 100% rename from website/README.md rename to old/website/README.md diff --git a/website/book.toml b/old/website/book.toml similarity index 100% rename from website/book.toml rename to old/website/book.toml diff --git a/website/book/1-getting-started/setup.md b/old/website/book/1-getting-started/setup.md similarity index 100% rename from website/book/1-getting-started/setup.md rename to old/website/book/1-getting-started/setup.md diff --git a/website/book/SUMMARY.md b/old/website/book/SUMMARY.md similarity index 100% rename from website/book/SUMMARY.md rename to old/website/book/SUMMARY.md diff --git a/website/book/introduction.md b/old/website/book/introduction.md similarity index 100% rename from website/book/introduction.md rename to old/website/book/introduction.md diff --git a/website/build.sh b/old/website/build.sh similarity index 100% rename from website/build.sh rename to old/website/build.sh diff --git a/website/config.toml b/old/website/config.toml similarity index 100% rename from website/config.toml rename to old/website/config.toml diff --git a/website/content/_index.md b/old/website/content/_index.md similarity index 100% rename from website/content/_index.md rename to old/website/content/_index.md diff --git a/website/content/faq.md b/old/website/content/faq.md similarity index 100% rename from website/content/faq.md rename to old/website/content/faq.md diff --git a/website/content/news.md b/old/website/content/news.md similarity index 100% rename from website/content/news.md rename to old/website/content/news.md diff --git a/website/sass/_markdown.scss b/old/website/sass/_markdown.scss similarity index 100% rename from website/sass/_markdown.scss rename to old/website/sass/_markdown.scss diff --git a/website/sass/_text.scss b/old/website/sass/_text.scss similarity index 100% rename from website/sass/_text.scss rename to old/website/sass/_text.scss diff --git a/website/sass/_ultility.scss b/old/website/sass/_ultility.scss similarity index 100% rename from website/sass/_ultility.scss rename to old/website/sass/_ultility.scss diff --git a/website/sass/juice.scss b/old/website/sass/juice.scss similarity index 100% rename from website/sass/juice.scss rename to old/website/sass/juice.scss diff --git a/website/static/favicon.ico b/old/website/static/favicon.ico similarity index 100% rename from website/static/favicon.ico rename to old/website/static/favicon.ico diff --git a/website/static/normalize.css b/old/website/static/normalize.css similarity index 100% rename from website/static/normalize.css rename to old/website/static/normalize.css diff --git a/website/static/prism.css b/old/website/static/prism.css similarity index 100% rename from website/static/prism.css rename to old/website/static/prism.css diff --git a/website/static/prism.js b/old/website/static/prism.js similarity index 100% rename from website/static/prism.js rename to old/website/static/prism.js diff --git a/website/static/syntax-theme.css b/old/website/static/syntax-theme.css similarity index 100% rename from website/static/syntax-theme.css rename to old/website/static/syntax-theme.css diff --git a/website/templates/_macros.html b/old/website/templates/_macros.html similarity index 100% rename from website/templates/_macros.html rename to old/website/templates/_macros.html diff --git a/website/templates/_variables.html b/old/website/templates/_variables.html similarity index 100% rename from website/templates/_variables.html rename to old/website/templates/_variables.html diff --git a/website/templates/index.html b/old/website/templates/index.html similarity index 100% rename from website/templates/index.html rename to old/website/templates/index.html diff --git a/website/templates/page.html b/old/website/templates/page.html similarity index 100% rename from website/templates/page.html rename to old/website/templates/page.html diff --git a/website/templates/shortcodes/issue.html b/old/website/templates/shortcodes/issue.html similarity index 100% rename from website/templates/shortcodes/issue.html rename to old/website/templates/shortcodes/issue.html From e64b1e277437139e2e078236d080000e7024ea3d Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 2 Feb 2024 20:55:31 -0800 Subject: [PATCH 02/11] Add some basic crates, fix added lints --- .../devcontainer.json | 0 .gitignore | 18 + Cargo.toml | 157 +++++++++ clippy.toml | 1 + {old/crates => crates}/java_string/Cargo.toml | 3 + {old/crates => crates}/java_string/README.md | 0 .../java_string/src/cesu8.rs | 9 +- .../crates => crates}/java_string/src/char.rs | 2 +- .../java_string/src/error.rs | 0 .../crates => crates}/java_string/src/iter.rs | 14 +- {old/crates => crates}/java_string/src/lib.rs | 0 .../java_string/src/owned.rs | 11 +- .../java_string/src/pattern.rs | 96 ++---- .../java_string/src/serde.rs | 19 +- .../java_string/src/slice.rs | 40 +-- .../java_string/src/validations.rs | 18 +- .../valence_ident/Cargo.toml | 3 + .../crates => crates}/valence_ident/README.md | 0 .../valence_ident/src/lib.rs | 2 +- .../valence_ident_macros/Cargo.toml | 3 + .../valence_ident_macros/README.md | 0 .../valence_ident_macros/src/lib.rs | 0 {old/crates => crates}/valence_nbt/Cargo.toml | 4 +- {old/crates => crates}/valence_nbt/README.md | 0 .../valence_nbt/src/binary.rs | 0 .../valence_nbt/src/binary/decode.rs | 0 .../valence_nbt/src/binary/encode.rs | 2 +- .../valence_nbt/src/binary/error.rs | 0 .../valence_nbt/src/binary/modified_utf8.rs | 4 +- .../valence_nbt/src/binary/tests.rs | 0 .../valence_nbt/src/compound.rs | 81 +++-- .../crates => crates}/valence_nbt/src/conv.rs | 0 {old/crates => crates}/valence_nbt/src/lib.rs | 17 - .../crates => crates}/valence_nbt/src/list.rs | 326 +++++++++--------- .../valence_nbt/src/serde.rs | 0 .../valence_nbt/src/serde/de.rs | 10 +- .../valence_nbt/src/serde/ser.rs | 13 +- .../valence_nbt/src/serde/tests.rs | 0 .../crates => crates}/valence_nbt/src/snbt.rs | 4 +- {old/crates => crates}/valence_nbt/src/tag.rs | 0 .../valence_nbt/src/value.rs | 2 +- .../crates => crates}/valence_text/Cargo.toml | 5 +- {old/crates => crates}/valence_text/README.md | 0 .../valence_text/src/color.rs | 8 +- .../valence_text/src/into_text.rs | 0 .../crates => crates}/valence_text/src/lib.rs | 2 +- .../valence_text/src/tests.rs | 0 rustfmt.toml | 11 + src/lib.rs | 0 49 files changed, 529 insertions(+), 356 deletions(-) rename {old/.devcontainer => .devcontainer}/devcontainer.json (100%) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 clippy.toml rename {old/crates => crates}/java_string/Cargo.toml (93%) rename {old/crates => crates}/java_string/README.md (100%) rename {old/crates => crates}/java_string/src/cesu8.rs (96%) rename {old/crates => crates}/java_string/src/char.rs (99%) rename {old/crates => crates}/java_string/src/error.rs (100%) rename {old/crates => crates}/java_string/src/iter.rs (98%) rename {old/crates => crates}/java_string/src/lib.rs (100%) rename {old/crates => crates}/java_string/src/owned.rs (99%) rename {old/crates => crates}/java_string/src/pattern.rs (85%) rename {old/crates => crates}/java_string/src/serde.rs (94%) rename {old/crates => crates}/java_string/src/slice.rs (99%) rename {old/crates => crates}/java_string/src/validations.rs (96%) rename {old/crates => crates}/valence_ident/Cargo.toml (93%) rename {old/crates => crates}/valence_ident/README.md (100%) rename {old/crates => crates}/valence_ident/src/lib.rs (99%) rename {old/crates => crates}/valence_ident_macros/Cargo.toml (93%) rename {old/crates => crates}/valence_ident_macros/README.md (100%) rename {old/crates => crates}/valence_ident_macros/src/lib.rs (100%) rename {old/crates => crates}/valence_nbt/Cargo.toml (94%) rename {old/crates => crates}/valence_nbt/README.md (100%) rename {old/crates => crates}/valence_nbt/src/binary.rs (100%) rename {old/crates => crates}/valence_nbt/src/binary/decode.rs (100%) rename {old/crates => crates}/valence_nbt/src/binary/encode.rs (99%) rename {old/crates => crates}/valence_nbt/src/binary/error.rs (100%) rename {old/crates => crates}/valence_nbt/src/binary/modified_utf8.rs (97%) rename {old/crates => crates}/valence_nbt/src/binary/tests.rs (100%) rename {old/crates => crates}/valence_nbt/src/compound.rs (90%) rename {old/crates => crates}/valence_nbt/src/conv.rs (100%) rename {old/crates => crates}/valence_nbt/src/lib.rs (85%) rename {old/crates => crates}/valence_nbt/src/list.rs (72%) rename {old/crates => crates}/valence_nbt/src/serde.rs (100%) rename {old/crates => crates}/valence_nbt/src/serde/de.rs (98%) rename {old/crates => crates}/valence_nbt/src/serde/ser.rs (98%) rename {old/crates => crates}/valence_nbt/src/serde/tests.rs (100%) rename {old/crates => crates}/valence_nbt/src/snbt.rs (99%) rename {old/crates => crates}/valence_nbt/src/tag.rs (100%) rename {old/crates => crates}/valence_nbt/src/value.rs (99%) rename {old/crates => crates}/valence_text/Cargo.toml (89%) rename {old/crates => crates}/valence_text/README.md (100%) rename {old/crates => crates}/valence_text/src/color.rs (98%) rename {old/crates => crates}/valence_text/src/into_text.rs (100%) rename {old/crates => crates}/valence_text/src/lib.rs (99%) rename {old/crates => crates}/valence_text/src/tests.rs (100%) create mode 100644 rustfmt.toml create mode 100644 src/lib.rs diff --git a/old/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json similarity index 100% rename from old/.devcontainer/devcontainer.json rename to .devcontainer/devcontainer.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..a7f663825 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +/target +Cargo.lock +.vscode +.idea +*.iml +.gradle +/extractor/build +/extractor/out +/extractor/classes +/extractor/run +/extractor/bin +rust-mc-bot +.asset_cache/ +/velocity +flamegraph*.svg +perf.data +perf.data.old +/graph.svg diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..c066556c3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,157 @@ +[package] +name = "valence" +version.workspace = true +edition.workspace = true +description = "A framework for building Minecraft servers in Rust." +documentation.workspace = true +repository.workspace = true +readme = "README.md" +license.workspace = true +keywords = ["minecraft", "gamedev", "server", "ecs"] +categories = ["game-engines"] + +[lints] +workspace = true + +#### WORKSPACE #### + +[profile.dev.package."*"] +opt-level = 3 + +[profile.dev] +opt-level = 1 + +[workspace] +members = ["crates/*"] +resolver = "2" + +[workspace.package] +version = "0.2.0-alpha.1+mc.1.20.1" +edition = "2021" +repository = "https://github.com/valence-rs/valence" +documentation = "https://docs.rs/valence/" +license = "MIT" + +[workspace.dependencies] +byteorder = "1.5.0" +cesu8 = "1.1.0" +indexmap = "2.2.2" +java_string = { path = "crates/java_string", version = "0.1.2" } +proc-macro2 = "1.0.78" +quote = "1.0.35" +serde = "1.0.196" +syn = { version = "2.0.48", features = ["full"] } +thiserror = "1.0.56" +uuid = "1.7.0" +valence_ident = { path = "crates/valence_ident", version = "0.2.0-alpha.1" } +valence_ident_macros = { path = "crates/valence_ident_macros", version = "0.2.0-alpha.1" } +pretty_assertions = "1.4.0" +serde_json = "1.0.113" +valence_nbt = { path = "crates/valence_nbt", version = "0.8.0" } + +[workspace.lints.rust] +elided_lifetimes_in_paths = "allow" # Warned by `future_incompatible`. +future_incompatible = "warn" +missing_debug_implementations = "warn" +# missing_docs = "warn" +nonstandard_style = "warn" +rust_2018_idioms = "warn" +trivial_numeric_casts = "warn" +unreachable_pub = "warn" +unused_import_braces = "warn" +unused_lifetimes = "warn" + +[workspace.lints.clippy] +alloc_instead_of_core = "warn" +as_ptr_cast_mut = "warn" +as_underscore = "warn" +bool_to_int_with_if = "warn" +case_sensitive_file_extension_comparisons = "warn" +cast_lossless = "warn" +checked_conversions = "warn" +cloned_instead_of_copied = "warn" +copy_iterator = "warn" +dbg_macro = "warn" +doc_link_with_quotes = "warn" +doc_markdown = "warn" +empty_enum_variants_with_brackets = "warn" +empty_structs_with_brackets = "warn" +explicit_deref_methods = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +format_push_string = "warn" +from_iter_instead_of_collect = "warn" +get_unwrap = "warn" +if_then_some_else_none = "warn" +ignored_unit_patterns = "warn" +implicit_clone = "warn" +inconsistent_struct_constructor = "warn" +inefficient_to_string = "warn" +infinite_loop = "warn" +into_iter_without_iter = "warn" +invalid_upcast_comparisons = "warn" +iter_filter_is_ok = "warn" +iter_filter_is_some = "warn" +iter_not_returning_iterator = "warn" +iter_over_hash_type = "warn" # Requires justification +iter_without_into_iter = "warn" +large_stack_arrays = "warn" +large_types_passed_by_value = "warn" +macro_use_imports = "warn" +manual_assert = "warn" +manual_instant_elapsed = "warn" +manual_is_variant_and = "warn" +manual_let_else = "warn" +manual_ok_or = "warn" +manual_string_new = "warn" +map_unwrap_or = "warn" +match_bool = "warn" +match_wildcard_for_single_variants = "warn" +mismatching_type_param_order = "warn" +missing_fields_in_debug = "warn" +mixed_read_write_in_expression = "warn" +mod_module_files = "warn" +# multiple_inherent_impl = "warn" +mut_mut = "warn" +mutex_atomic = "warn" +needless_bitwise_bool = "warn" +needless_continue = "warn" +needless_for_each = "warn" +needless_raw_string_hashes = "warn" +needless_raw_strings = "warn" +negative_feature_names = "warn" +no_mangle_with_rust_abi = "warn" +option_as_ref_cloned = "warn" +pub_underscore_fields = "warn" +rc_buffer = "warn" +rc_mutex = "warn" +redundant_else = "warn" +redundant_feature_names = "warn" +ref_patterns = "warn" +rest_pat_in_fully_bound_structs = "warn" +semicolon_outside_block = "warn" +str_to_string = "warn" +string_lit_chars_any = "warn" +string_to_string = "warn" +struct_field_names = "warn" +tests_outside_test_module = "warn" +todo = "warn" +trivially_copy_pass_by_ref = "warn" +try_err = "warn" +# undocumented_unsafe_blocks = "warn" +uninlined_format_args = "warn" +unnecessary_join = "warn" +# unnecessary_safety_doc = "warn" +unnecessary_self_imports = "warn" +unneeded_field_pattern = "warn" +unnested_or_patterns = "warn" +unseparated_literal_suffix = "warn" +unused_self = "warn" +used_underscore_binding = "warn" +wildcard_dependencies = "warn" +zero_sized_map_values = "warn" + +[workspace.lints.rustdoc] +unescaped_backticks = "warn" diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 000000000..0ac765717 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +semicolon-outside-block-ignore-multiline = true diff --git a/old/crates/java_string/Cargo.toml b/crates/java_string/Cargo.toml similarity index 93% rename from old/crates/java_string/Cargo.toml rename to crates/java_string/Cargo.toml index 0465f63c2..b555e5a8c 100644 --- a/old/crates/java_string/Cargo.toml +++ b/crates/java_string/Cargo.toml @@ -14,3 +14,6 @@ serde = ["dep:serde"] [dependencies] serde = { workspace = true, optional = true } + +[lints] +workspace = true diff --git a/old/crates/java_string/README.md b/crates/java_string/README.md similarity index 100% rename from old/crates/java_string/README.md rename to crates/java_string/README.md diff --git a/old/crates/java_string/src/cesu8.rs b/crates/java_string/src/cesu8.rs similarity index 96% rename from old/crates/java_string/src/cesu8.rs rename to crates/java_string/src/cesu8.rs index eb94ee6c1..34ee4a1b1 100644 --- a/old/crates/java_string/src/cesu8.rs +++ b/crates/java_string/src/cesu8.rs @@ -114,7 +114,7 @@ impl JavaStr { impl JavaString { /// Converts from Java's [modified UTF-8](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8) format to a `JavaString`. /// - /// See [JavaStr::from_modified_utf8]. + /// See [`JavaStr::from_modified_utf8`]. #[inline] pub fn from_modified_utf8(bytes: Vec) -> Result { match JavaString::from_full_utf8(bytes) { @@ -184,6 +184,7 @@ impl JavaString { } 3 => { let third = next_cont!(Some(2)); + #[allow(clippy::unnested_or_patterns)] // Justification: readability match (first, second) { // These are valid UTF-8, so pass them through. (0xe0, 0xa0..=0xbf) @@ -227,7 +228,7 @@ impl JavaString { /// Converts to Java's [modified UTF-8](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8) format. /// - /// See [JavaStr::to_modified_utf8]. + /// See [`JavaStr::to_modified_utf8`]. #[inline] #[must_use] pub fn into_modified_utf8(self) -> Vec { @@ -241,7 +242,7 @@ impl JavaString { #[inline] fn dec_surrogate(second: u8, third: u8) -> u32 { - 0xd000 | ((second & CONT_MASK) as u32) << 6 | (third & CONT_MASK) as u32 + 0xd000 | u32::from(second & CONT_MASK) << 6 | u32::from(third & CONT_MASK) } #[inline] @@ -255,7 +256,7 @@ fn dec_surrogates(second: u8, third: u8, fifth: u8, sixth: u8) -> [u8; 4] { // Convert to UTF-8. // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx [ - 0b1111_0000u8 | ((c & 0b1_1100_0000_0000_0000_0000) >> 18) as u8, + 0b1111_0000_u8 | ((c & 0b1_1100_0000_0000_0000_0000) >> 18) as u8, TAG_CONT | ((c & 0b0_0011_1111_0000_0000_0000) >> 12) as u8, TAG_CONT | ((c & 0b0_0000_0000_1111_1100_0000) >> 6) as u8, TAG_CONT | (c & 0b0_0000_0000_0000_0011_1111) as u8, diff --git a/old/crates/java_string/src/char.rs b/crates/java_string/src/char.rs similarity index 99% rename from old/crates/java_string/src/char.rs rename to crates/java_string/src/char.rs index f338a25c4..f21e7d7b7 100644 --- a/old/crates/java_string/src/char.rs +++ b/crates/java_string/src/char.rs @@ -170,7 +170,7 @@ impl JavaCodePoint { } /// Encodes this `JavaCodePoint` into semi UTF-8, that is, UTF-8 with - /// surrogate code points. See also [char::encode_utf8]. + /// surrogate code points. See also [`char::encode_utf8`]. /// /// ``` /// # use java_string::JavaCodePoint; diff --git a/old/crates/java_string/src/error.rs b/crates/java_string/src/error.rs similarity index 100% rename from old/crates/java_string/src/error.rs rename to crates/java_string/src/error.rs diff --git a/old/crates/java_string/src/iter.rs b/crates/java_string/src/iter.rs similarity index 98% rename from old/crates/java_string/src/iter.rs rename to crates/java_string/src/iter.rs index 3762f6d72..f93605393 100644 --- a/old/crates/java_string/src/iter.rs +++ b/crates/java_string/src/iter.rs @@ -649,17 +649,17 @@ where } match self.next_match_back() { - Some((index, len)) => unsafe { + Some((index, len)) => { // SAFETY: pattern guarantees valid indices - let elt = self.haystack.get_unchecked(index + len..self.end); + let elt = unsafe { self.haystack.get_unchecked(index + len..self.end) }; self.end = index + len; Some(elt) - }, - None => unsafe { - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. + } + None => { self.finished = true; - Some(self.haystack.get_unchecked(self.start..self.end)) - }, + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. + Some(unsafe { self.haystack.get_unchecked(self.start..self.end) }) + } } } } diff --git a/old/crates/java_string/src/lib.rs b/crates/java_string/src/lib.rs similarity index 100% rename from old/crates/java_string/src/lib.rs rename to crates/java_string/src/lib.rs diff --git a/old/crates/java_string/src/owned.rs b/crates/java_string/src/owned.rs similarity index 99% rename from old/crates/java_string/src/owned.rs rename to crates/java_string/src/owned.rs index 786855b58..060346c10 100644 --- a/old/crates/java_string/src/owned.rs +++ b/crates/java_string/src/owned.rs @@ -199,7 +199,7 @@ impl JavaString { /// assert!(string_with_error.into_string().is_err()); /// ``` pub fn into_string(self) -> Result { - run_utf8_full_validation_from_semi(self.as_bytes()).map(|_| unsafe { + run_utf8_full_validation_from_semi(self.as_bytes()).map(|()| unsafe { // SAFETY: validation succeeded self.into_string_unchecked() }) @@ -357,9 +357,8 @@ impl JavaString { /// ``` #[inline] pub fn remove(&mut self, idx: usize) -> JavaCodePoint { - let ch = match self[idx..].chars().next() { - Some(ch) => ch, - None => panic!("cannot remove a char from the end of a string"), + let Some(ch) = self[idx..].chars().next() else { + panic!("cannot remove a char from the end of a string") }; let next = idx + ch.len_utf8(); @@ -829,13 +828,13 @@ impl Extend for JavaString { impl<'a> Extend<&'a char> for JavaString { fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().cloned()) + self.extend(iter.into_iter().copied()) } } impl<'a> Extend<&'a JavaCodePoint> for JavaString { fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().cloned()) + self.extend(iter.into_iter().copied()) } } diff --git a/old/crates/java_string/src/pattern.rs b/crates/java_string/src/pattern.rs similarity index 85% rename from old/crates/java_string/src/pattern.rs rename to crates/java_string/src/pattern.rs index 06cc78041..a17d374a9 100644 --- a/old/crates/java_string/src/pattern.rs +++ b/crates/java_string/src/pattern.rs @@ -32,21 +32,13 @@ unsafe impl JavaStrPattern for char { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next()?; - if ch == *self { - Some(ch.len_utf8()) - } else { - None - } + (ch == *self).then(|| ch.len_utf8()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next_back()?; - if ch == *self { - Some(ch.len_utf8()) - } else { - None - } + (ch == *self).then(|| ch.len_utf8()) } #[inline] @@ -68,21 +60,13 @@ unsafe impl JavaStrPattern for JavaCodePoint { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next()?; - if ch == *self { - Some(ch.len_utf8()) - } else { - None - } + (ch == *self).then(|| ch.len_utf8()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next_back()?; - if ch == *self { - Some(ch.len_utf8()) - } else { - None - } + (ch == *self).then(|| ch.len_utf8()) } #[inline] @@ -103,20 +87,18 @@ unsafe impl JavaStrPattern for JavaCodePoint { unsafe impl JavaStrPattern for &str { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { - if haystack.as_bytes().starts_with(self.as_bytes()) { - Some(self.len()) - } else { - None - } + haystack + .as_bytes() + .starts_with(self.as_bytes()) + .then_some(self.len()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { - if haystack.as_bytes().ends_with(self.as_bytes()) { - Some(self.len()) - } else { - None - } + haystack + .as_bytes() + .ends_with(self.as_bytes()) + .then_some(self.len()) } #[inline] @@ -133,20 +115,18 @@ unsafe impl JavaStrPattern for &str { unsafe impl JavaStrPattern for &JavaStr { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { - if haystack.as_bytes().starts_with(self.as_bytes()) { - Some(self.len()) - } else { - None - } + haystack + .as_bytes() + .starts_with(self.as_bytes()) + .then(|| self.len()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { - if haystack.as_bytes().ends_with(self.as_bytes()) { - Some(self.len()) - } else { - None - } + haystack + .as_bytes() + .ends_with(self.as_bytes()) + .then(|| self.len()) } #[inline] @@ -167,21 +147,13 @@ where #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next()?; - if self(ch) { - Some(ch.len_utf8()) - } else { - None - } + self(ch).then(|| ch.len_utf8()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next_back()?; - if self(ch) { - Some(ch.len_utf8()) - } else { - None - } + self(ch).then(|| ch.len_utf8()) } #[inline] @@ -205,21 +177,13 @@ unsafe impl JavaStrPattern for &[char] { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next()?; - if self.iter().any(|c| ch == *c) { - Some(ch.len_utf8()) - } else { - None - } + self.iter().any(|c| ch == *c).then(|| ch.len_utf8()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next_back()?; - if self.iter().any(|c| ch == *c) { - Some(ch.len_utf8()) - } else { - None - } + self.iter().any(|c| ch == *c).then(|| ch.len_utf8()) } #[inline] @@ -243,21 +207,13 @@ unsafe impl JavaStrPattern for &[JavaCodePoint] { #[inline] fn prefix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next()?; - if self.contains(&ch) { - Some(ch.len_utf8()) - } else { - None - } + self.contains(&ch).then(|| ch.len_utf8()) } #[inline] fn suffix_len_in(&mut self, haystack: &JavaStr) -> Option { let ch = haystack.chars().next_back()?; - if self.contains(&ch) { - Some(ch.len_utf8()) - } else { - None - } + self.contains(&ch).then(|| ch.len_utf8()) } #[inline] diff --git a/old/crates/java_string/src/serde.rs b/crates/java_string/src/serde.rs similarity index 94% rename from old/crates/java_string/src/serde.rs rename to crates/java_string/src/serde.rs index e1c152d11..44281c4fe 100644 --- a/old/crates/java_string/src/serde.rs +++ b/crates/java_string/src/serde.rs @@ -175,7 +175,7 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { where E: Error, { - self.visit_i32(v as i32) + self.visit_i32(v.into()) } #[inline] @@ -183,7 +183,7 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { where E: Error, { - self.visit_i32(v as i32) + self.visit_i32(v.into()) } fn visit_i32(self, v: i32) -> Result @@ -191,7 +191,7 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { E: Error, { if v < 0 { - Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + Err(Error::invalid_value(Unexpected::Signed(v.into()), &self)) } else { self.visit_u32(v as u32) } @@ -213,7 +213,7 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { where E: Error, { - self.visit_u32(v as u32) + self.visit_u32(v.into()) } #[inline] @@ -221,7 +221,7 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { where E: Error, { - self.visit_u32(v as u32) + self.visit_u32(v.into()) } fn visit_u32(self, v: u32) -> Result @@ -229,17 +229,16 @@ impl<'de> Visitor<'de> for JavaCodePointVisitor { E: Error, { JavaCodePoint::from_u32(v) - .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v as u64), &self)) + .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v.into()), &self)) } fn visit_u64(self, v: u64) -> Result where E: Error, { - if v > u32::MAX as u64 { - Err(Error::invalid_value(Unexpected::Unsigned(v), &self)) - } else { - self.visit_u32(v as u32) + match u32::try_from(v) { + Ok(v) => self.visit_u32(v), + Err(_) => Err(Error::invalid_value(Unexpected::Unsigned(v), &self)) } } diff --git a/old/crates/java_string/src/slice.rs b/crates/java_string/src/slice.rs similarity index 99% rename from old/crates/java_string/src/slice.rs rename to crates/java_string/src/slice.rs index d5dfd17ca..ad976ed40 100644 --- a/old/crates/java_string/src/slice.rs +++ b/crates/java_string/src/slice.rs @@ -23,8 +23,8 @@ use crate::{ SplitInclusive, SplitN, SplitTerminator, SplitWhitespace, Utf8Error, }; -#[repr(transparent)] #[derive(PartialEq, Eq, PartialOrd, Ord)] +#[repr(transparent)] pub struct JavaStr { inner: [u8], } @@ -1435,7 +1435,7 @@ impl JavaStr { self.transform_string(str::to_lowercase, |ch| ch) } - /// See [str::to_uppercase]. + /// See [`str::to_uppercase`]. /// /// ``` /// # use java_string::{JavaCodePoint, JavaStr, JavaString}; @@ -1459,21 +1459,21 @@ impl JavaStr { self.transform_string(str::to_uppercase, |ch| ch) } - /// See [str::trim]. + /// See [`str::trim`]. #[inline] #[must_use] pub fn trim(&self) -> &JavaStr { self.trim_matches(|c: JavaCodePoint| c.is_whitespace()) } - /// See [str::trim_end]. + /// See [`str::trim_end`]. #[inline] #[must_use] pub fn trim_end(&self) -> &JavaStr { self.trim_end_matches(|c: JavaCodePoint| c.is_whitespace()) } - /// See [str::trim_end_matches]. + /// See [`str::trim_end_matches`]. /// /// ``` /// # use java_string::{JavaCodePoint, JavaStr}; @@ -1509,7 +1509,7 @@ impl JavaStr { str } - /// See [str::trim_matches]. + /// See [`str::trim_matches`]. /// /// ``` /// # use java_string::{JavaCodePoint, JavaStr}; @@ -1549,14 +1549,14 @@ impl JavaStr { str } - /// See [str::trim_start]. + /// See [`str::trim_start`]. #[inline] #[must_use] pub fn trim_start(&self) -> &JavaStr { self.trim_start_matches(|c: JavaCodePoint| c.is_whitespace()) } - /// See [str::trim_start_matches]. + /// See [`str::trim_start_matches`]. /// /// ``` /// # use java_string::{JavaCodePoint, JavaStr}; @@ -1987,35 +1987,35 @@ impl PartialEq for str { impl<'a> PartialEq for &'a str { #[inline] fn eq(&self, other: &JavaStr) -> bool { - *self == other + self.as_bytes() == &other.inner } } impl PartialEq for JavaStr { #[inline] fn eq(&self, other: &str) -> bool { - self == JavaStr::from_str(other) + &self.inner == other.as_bytes() } } impl<'a> PartialEq<&'a str> for JavaStr { #[inline] fn eq(&self, other: &&'a str) -> bool { - self == *other + &self.inner == other.as_bytes() } } impl<'a> PartialEq for &'a JavaStr { #[inline] fn eq(&self, other: &JavaStr) -> bool { - *self == other + self.inner == other.inner } } impl<'a> PartialEq<&'a JavaStr> for JavaStr { #[inline] fn eq(&self, other: &&'a JavaStr) -> bool { - self == *other + self.inner == other.inner } } @@ -2067,20 +2067,14 @@ pub unsafe trait JavaStrSliceIndex: private_slice_index::Sealed + Sized { #[inline] fn get(self, slice: &JavaStr) -> Option<&JavaStr> { - if self.check_bounds(slice) { - Some(unsafe { &*self.get_unchecked(slice) }) - } else { - None - } + self.check_bounds(slice) + .then(|| unsafe { &*self.get_unchecked(slice) }) } #[inline] fn get_mut(self, slice: &mut JavaStr) -> Option<&mut JavaStr> { - if self.check_bounds(slice) { - Some(unsafe { &mut *self.get_unchecked_mut(slice) }) - } else { - None - } + self.check_bounds(slice) + .then(|| unsafe { &mut *self.get_unchecked_mut(slice) }) } #[inline] diff --git a/old/crates/java_string/src/validations.rs b/crates/java_string/src/validations.rs similarity index 96% rename from old/crates/java_string/src/validations.rs rename to crates/java_string/src/validations.rs index 102783f55..d901863f3 100644 --- a/old/crates/java_string/src/validations.rs +++ b/crates/java_string/src/validations.rs @@ -31,7 +31,7 @@ pub(crate) unsafe fn next_code_point<'a, I: Iterator>(bytes: &mut // Decode UTF-8 let x = *bytes.next()?; if x < 128 { - return Some(x as u32); + return Some(x.into()); } // Multibyte case follows @@ -48,7 +48,7 @@ pub(crate) unsafe fn next_code_point<'a, I: Iterator>(bytes: &mut // SAFETY: `bytes` produces an UTF-8-like string, // so the iterator must produce a value here. let z = unsafe { *bytes.next().unwrap_unchecked() }; - let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z); + let y_z = utf8_acc_cont_byte((y & CONT_MASK).into(), z); ch = init << 12 | y_z; if x >= 0xf0 { // [x y z w] case @@ -72,7 +72,7 @@ pub(crate) unsafe fn next_code_point_reverse<'a, I: DoubleEndedIterator Option { // Decode UTF-8 let w = match *bytes.next_back()? { - next_byte if next_byte < 128 => return Some(next_byte as u32), + next_byte if next_byte < 128 => return Some(next_byte.into()), back_byte => back_byte, }; @@ -258,7 +258,7 @@ pub(crate) const fn utf8_char_width(first_byte: u8) -> usize { 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - UTF8_CHAR_WIDTH[first_byte as usize] as _ + UTF8_CHAR_WIDTH[first_byte as usize] as usize } #[inline] @@ -284,11 +284,7 @@ pub(crate) fn slice_error_fail(s: &JavaStr, begin: usize, end: usize) -> ! { // 2. begin <= end assert!( begin <= end, - "begin <= end ({} <= {}) when slicing `{}`{}", - begin, - end, - s_trunc, - ellipsis + "begin <= end ({begin} <= {end}) when slicing `{s_trunc}`{ellipsis}", ); // 3. character boundary @@ -303,8 +299,8 @@ pub(crate) fn slice_error_fail(s: &JavaStr, begin: usize, end: usize) -> ! { let ch = s[char_start..].chars().next().unwrap(); let char_range = char_start..char_start + ch.len_utf8(); panic!( - "byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}", - index, ch, char_range, s_trunc, ellipsis + "byte index {index} is not a char boundary; it is inside {ch:?} (bytes {char_range:?}) of \ + `{s_trunc}`{ellipsis}", ); } diff --git a/old/crates/valence_ident/Cargo.toml b/crates/valence_ident/Cargo.toml similarity index 93% rename from old/crates/valence_ident/Cargo.toml rename to crates/valence_ident/Cargo.toml index 09b5220ab..13887a8ce 100644 --- a/old/crates/valence_ident/Cargo.toml +++ b/crates/valence_ident/Cargo.toml @@ -12,3 +12,6 @@ license.workspace = true thiserror.workspace = true serde.workspace = true valence_ident_macros.workspace = true + +[lints] +workspace = true diff --git a/old/crates/valence_ident/README.md b/crates/valence_ident/README.md similarity index 100% rename from old/crates/valence_ident/README.md rename to crates/valence_ident/README.md diff --git a/old/crates/valence_ident/src/lib.rs b/crates/valence_ident/src/lib.rs similarity index 99% rename from old/crates/valence_ident/src/lib.rs rename to crates/valence_ident/src/lib.rs index 10925f0e9..994cfac85 100644 --- a/old/crates/valence_ident/src/lib.rs +++ b/crates/valence_ident/src/lib.rs @@ -57,7 +57,7 @@ pub struct Ident { pub struct IdentError(pub String); impl<'a> Ident> { - pub fn new(string: impl Into>) -> Result { + pub fn new>>(string: S) -> Result { parse(string.into()) } } diff --git a/old/crates/valence_ident_macros/Cargo.toml b/crates/valence_ident_macros/Cargo.toml similarity index 93% rename from old/crates/valence_ident_macros/Cargo.toml rename to crates/valence_ident_macros/Cargo.toml index f83651c8c..98f26bb90 100644 --- a/old/crates/valence_ident_macros/Cargo.toml +++ b/crates/valence_ident_macros/Cargo.toml @@ -15,3 +15,6 @@ proc-macro = true proc-macro2.workspace = true quote.workspace = true syn = { workspace = true, features = ["full"] } + +[lints] +workspace = true diff --git a/old/crates/valence_ident_macros/README.md b/crates/valence_ident_macros/README.md similarity index 100% rename from old/crates/valence_ident_macros/README.md rename to crates/valence_ident_macros/README.md diff --git a/old/crates/valence_ident_macros/src/lib.rs b/crates/valence_ident_macros/src/lib.rs similarity index 100% rename from old/crates/valence_ident_macros/src/lib.rs rename to crates/valence_ident_macros/src/lib.rs diff --git a/old/crates/valence_nbt/Cargo.toml b/crates/valence_nbt/Cargo.toml similarity index 94% rename from old/crates/valence_nbt/Cargo.toml rename to crates/valence_nbt/Cargo.toml index 3c60fd038..bdef82083 100644 --- a/old/crates/valence_nbt/Cargo.toml +++ b/crates/valence_nbt/Cargo.toml @@ -13,7 +13,6 @@ repository.workspace = true binary = ["dep:byteorder", "dep:cesu8"] java_string = ["dep:java_string"] snbt = [] -# When enabled, the order of fields in compounds are preserved. preserve_order = ["dep:indexmap"] serde = ["dep:serde", "dep:thiserror", "indexmap?/serde"] @@ -30,3 +29,6 @@ valence_ident = { workspace = true, optional = true } [dev-dependencies] pretty_assertions.workspace = true serde_json.workspace = true + +[lints] +workspace = true diff --git a/old/crates/valence_nbt/README.md b/crates/valence_nbt/README.md similarity index 100% rename from old/crates/valence_nbt/README.md rename to crates/valence_nbt/README.md diff --git a/old/crates/valence_nbt/src/binary.rs b/crates/valence_nbt/src/binary.rs similarity index 100% rename from old/crates/valence_nbt/src/binary.rs rename to crates/valence_nbt/src/binary.rs diff --git a/old/crates/valence_nbt/src/binary/decode.rs b/crates/valence_nbt/src/binary/decode.rs similarity index 100% rename from old/crates/valence_nbt/src/binary/decode.rs rename to crates/valence_nbt/src/binary/decode.rs diff --git a/old/crates/valence_nbt/src/binary/encode.rs b/crates/valence_nbt/src/binary/encode.rs similarity index 99% rename from old/crates/valence_nbt/src/binary/encode.rs rename to crates/valence_nbt/src/binary/encode.rs index 8cc50b811..037326fbd 100644 --- a/old/crates/valence_nbt/src/binary/encode.rs +++ b/crates/valence_nbt/src/binary/encode.rs @@ -259,7 +259,7 @@ impl EncodeState { where S: ToModifiedUtf8 + Hash + Ord, { - for (k, v) in c.iter() { + for (k, v) in c { self.write_tag(v.tag())?; self.write_string(k)?; self.write_value(v)?; diff --git a/old/crates/valence_nbt/src/binary/error.rs b/crates/valence_nbt/src/binary/error.rs similarity index 100% rename from old/crates/valence_nbt/src/binary/error.rs rename to crates/valence_nbt/src/binary/error.rs diff --git a/old/crates/valence_nbt/src/binary/modified_utf8.rs b/crates/valence_nbt/src/binary/modified_utf8.rs similarity index 97% rename from old/crates/valence_nbt/src/binary/modified_utf8.rs rename to crates/valence_nbt/src/binary/modified_utf8.rs index 491745de5..8b6836366 100644 --- a/old/crates/valence_nbt/src/binary/modified_utf8.rs +++ b/crates/valence_nbt/src/binary/modified_utf8.rs @@ -62,13 +62,13 @@ const fn utf8_char_width(first_byte: u8) -> usize { 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - UTF8_CHAR_WIDTH[first_byte as usize] as _ + UTF8_CHAR_WIDTH[first_byte as usize] as usize } fn encode_surrogate(surrogate: u16) -> [u8; 3] { debug_assert!((0xd800..=0xdfff).contains(&surrogate)); - const TAG_CONT_U8: u8 = 0b1000_0000u8; + const TAG_CONT_U8: u8 = 0b1000_0000_u8; [ 0b11100000 | ((surrogate & 0b11110000_00000000) >> 12) as u8, TAG_CONT_U8 | ((surrogate & 0b00001111_11000000) >> 6) as u8, diff --git a/old/crates/valence_nbt/src/binary/tests.rs b/crates/valence_nbt/src/binary/tests.rs similarity index 100% rename from old/crates/valence_nbt/src/binary/tests.rs rename to crates/valence_nbt/src/binary/tests.rs diff --git a/old/crates/valence_nbt/src/compound.rs b/crates/valence_nbt/src/compound.rs similarity index 90% rename from old/crates/valence_nbt/src/compound.rs rename to crates/valence_nbt/src/compound.rs index 636bb2194..913cae533 100644 --- a/old/crates/valence_nbt/src/compound.rs +++ b/crates/valence_nbt/src/compound.rs @@ -219,8 +219,8 @@ where use indexmap::map::Entry as EntryImpl; match self.map.entry(k.into()) { - EntryImpl::Vacant(ve) => Entry::Vacant(VacantEntry { ve }), - EntryImpl::Occupied(oe) => Entry::Occupied(OccupiedEntry { oe }), + EntryImpl::Vacant(ve) => Entry::Vacant(VacantEntry { entry: ve }), + EntryImpl::Occupied(oe) => Entry::Occupied(OccupiedEntry { entry: oe }), } } @@ -421,7 +421,7 @@ where } } - pub fn or_insert(self, default: impl Into>) -> &'a mut Value { + pub fn or_insert>>(self, default: V) -> &'a mut Value { match self { Entry::Vacant(ve) => ve.insert(default), Entry::Occupied(oe) => oe.into_mut(), @@ -453,11 +453,23 @@ where } } +impl fmt::Debug for Entry<'_, S> +where + S: fmt::Debug + Ord, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Vacant(entry) => f.debug_tuple("Vacant").field(entry).finish(), + Self::Occupied(entry) => f.debug_tuple("Occupied").field(entry).finish(), + } + } +} + pub struct VacantEntry<'a, S = String> { #[cfg(not(feature = "preserve_order"))] - ve: std::collections::btree_map::VacantEntry<'a, S, Value>, + entry: std::collections::btree_map::VacantEntry<'a, S, Value>, #[cfg(feature = "preserve_order")] - ve: indexmap::map::VacantEntry<'a, S, Value>, + entry: indexmap::map::VacantEntry<'a, S, Value>, } impl<'a, S> VacantEntry<'a, S> @@ -465,19 +477,30 @@ where S: Ord + Hash, { pub fn key(&self) -> &S { - self.ve.key() + self.entry.key() + } + + pub fn insert>>(self, v: V) -> &'a mut Value { + self.entry.insert(v.into()) } +} - pub fn insert(self, v: impl Into>) -> &'a mut Value { - self.ve.insert(v.into()) +impl fmt::Debug for VacantEntry<'_, S> +where + S: fmt::Debug + Ord, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("VacantEntry") + .field("entry", &self.entry) + .finish() } } pub struct OccupiedEntry<'a, S = String> { #[cfg(not(feature = "preserve_order"))] - oe: std::collections::btree_map::OccupiedEntry<'a, S, Value>, + entry: std::collections::btree_map::OccupiedEntry<'a, S, Value>, #[cfg(feature = "preserve_order")] - oe: indexmap::map::OccupiedEntry<'a, S, Value>, + entry: indexmap::map::OccupiedEntry<'a, S, Value>, } impl<'a, S> OccupiedEntry<'a, S> @@ -485,40 +508,51 @@ where S: Hash + Ord, { pub fn key(&self) -> &S { - self.oe.key() + self.entry.key() } pub fn get(&self) -> &Value { - self.oe.get() + self.entry.get() } pub fn get_mut(&mut self) -> &mut Value { - self.oe.get_mut() + self.entry.get_mut() } pub fn into_mut(self) -> &'a mut Value { - self.oe.into_mut() + self.entry.into_mut() } - pub fn insert(&mut self, v: impl Into>) -> Value { - self.oe.insert(v.into()) + pub fn insert>>(&mut self, v: V) -> Value { + self.entry.insert(v.into()) } pub fn remove(self) -> Value { #[cfg(feature = "preserve_order")] return self.swap_remove(); #[cfg(not(feature = "preserve_order"))] - return self.oe.remove(); + return self.entry.remove(); } #[cfg(feature = "preserve_order")] pub fn swap_remove(self) -> Value { - self.oe.swap_remove() + self.entry.swap_remove() } #[cfg(feature = "preserve_order")] pub fn shift_remove(self) -> Value { - self.oe.shift_remove() + self.entry.shift_remove() + } +} + +impl fmt::Debug for OccupiedEntry<'_, S> +where + S: fmt::Debug + Ord, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OccupiedEntry") + .field("entry", &self.entry) + .finish() } } @@ -588,7 +622,7 @@ impl<'a, S> IntoIterator for &'a Compound { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Iter<'a, S = String> { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::Iter<'a, S, Value>, @@ -609,6 +643,7 @@ impl<'a, S> IntoIterator for &'a mut Compound { } } +#[derive(Debug)] pub struct IterMut<'a, S = String> { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::IterMut<'a, S, Value>, @@ -629,6 +664,7 @@ impl IntoIterator for Compound { } } +#[derive(Debug)] pub struct IntoIter { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::IntoIter>, @@ -638,7 +674,7 @@ pub struct IntoIter { impl_iterator_traits!((IntoIter) => (S, Value)); -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Keys<'a, S = String> { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::Keys<'a, S, Value>, @@ -648,7 +684,7 @@ pub struct Keys<'a, S = String> { impl_iterator_traits!((Keys<'a, S>) => &'a S); -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Values<'a, S = String> { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::Values<'a, S, Value>, @@ -658,6 +694,7 @@ pub struct Values<'a, S = String> { impl_iterator_traits!((Values<'a, S>) => &'a Value); +#[derive(Debug)] pub struct ValuesMut<'a, S = String> { #[cfg(not(feature = "preserve_order"))] iter: std::collections::btree_map::ValuesMut<'a, S, Value>, diff --git a/old/crates/valence_nbt/src/conv.rs b/crates/valence_nbt/src/conv.rs similarity index 100% rename from old/crates/valence_nbt/src/conv.rs rename to crates/valence_nbt/src/conv.rs diff --git a/old/crates/valence_nbt/src/lib.rs b/crates/valence_nbt/src/lib.rs similarity index 85% rename from old/crates/valence_nbt/src/lib.rs rename to crates/valence_nbt/src/lib.rs index f422dc9dd..683cd0ed9 100644 --- a/old/crates/valence_nbt/src/lib.rs +++ b/crates/valence_nbt/src/lib.rs @@ -1,21 +1,4 @@ #![doc = include_str!("../README.md")] -#![deny( - rustdoc::broken_intra_doc_links, - rustdoc::private_intra_doc_links, - rustdoc::missing_crate_level_docs, - rustdoc::invalid_codeblock_attributes, - rustdoc::invalid_rust_codeblocks, - rustdoc::bare_urls, - rustdoc::invalid_html_tags -)] -#![warn( - trivial_casts, - trivial_numeric_casts, - unused_lifetimes, - unused_import_braces, - unreachable_pub, - clippy::dbg_macro -)] #[cfg(feature = "binary")] pub use binary::{from_binary, to_binary}; diff --git a/old/crates/valence_nbt/src/list.rs b/crates/valence_nbt/src/list.rs similarity index 72% rename from old/crates/valence_nbt/src/list.rs rename to crates/valence_nbt/src/list.rs index 8068d9d72..1592501fc 100644 --- a/old/crates/valence_nbt/src/list.rs +++ b/crates/valence_nbt/src/list.rs @@ -161,7 +161,7 @@ impl List { /// multiple types inside it). Returns `true` if the value was added, /// `false` otherwise. #[must_use] - pub fn try_push(&mut self, value: impl Into>) -> bool { + pub fn try_push>>(&mut self, value: V) -> bool { let value = value.into(); match self { List::End => { @@ -276,7 +276,7 @@ impl List { /// /// Panics if the index is greater than the length of the list. #[must_use] - pub fn try_insert(&mut self, index: usize, value: impl Into>) -> bool { + pub fn try_insert>>(&mut self, index: usize, value: V) -> bool { let value = value.into(); #[cold] @@ -662,10 +662,12 @@ impl<'a, S> IntoIterator for &'a mut List { } /// The owned iterator type for [`List`]. +#[derive(Clone, Debug)] pub struct IntoIter { inner: IntoIterInner, } +#[derive(Clone, Debug)] enum IntoIterInner { End, Byte(std::vec::IntoIter), @@ -686,78 +688,78 @@ impl Iterator for IntoIter { type Item = Value; fn next(&mut self) -> Option { - match self.inner { + match &mut self.inner { IntoIterInner::End => None, - IntoIterInner::Byte(ref mut i) => i.next().map(Value::Byte), - IntoIterInner::Short(ref mut i) => i.next().map(Value::Short), - IntoIterInner::Int(ref mut i) => i.next().map(Value::Int), - IntoIterInner::Long(ref mut i) => i.next().map(Value::Long), - IntoIterInner::Float(ref mut i) => i.next().map(Value::Float), - IntoIterInner::Double(ref mut i) => i.next().map(Value::Double), - IntoIterInner::ByteArray(ref mut i) => i.next().map(Value::ByteArray), - IntoIterInner::String(ref mut i) => i.next().map(Value::String), - IntoIterInner::List(ref mut i) => i.next().map(Value::List), - IntoIterInner::Compound(ref mut i) => i.next().map(Value::Compound), - IntoIterInner::IntArray(ref mut i) => i.next().map(Value::IntArray), - IntoIterInner::LongArray(ref mut i) => i.next().map(Value::LongArray), + IntoIterInner::Byte(i) => i.next().map(Value::Byte), + IntoIterInner::Short(i) => i.next().map(Value::Short), + IntoIterInner::Int(i) => i.next().map(Value::Int), + IntoIterInner::Long(i) => i.next().map(Value::Long), + IntoIterInner::Float(i) => i.next().map(Value::Float), + IntoIterInner::Double(i) => i.next().map(Value::Double), + IntoIterInner::ByteArray(i) => i.next().map(Value::ByteArray), + IntoIterInner::String(i) => i.next().map(Value::String), + IntoIterInner::List(i) => i.next().map(Value::List), + IntoIterInner::Compound(i) => i.next().map(Value::Compound), + IntoIterInner::IntArray(i) => i.next().map(Value::IntArray), + IntoIterInner::LongArray(i) => i.next().map(Value::LongArray), } } fn size_hint(&self) -> (usize, Option) { - match self.inner { + match &self.inner { IntoIterInner::End => (0, Some(0)), - IntoIterInner::Byte(ref i) => i.size_hint(), - IntoIterInner::Short(ref i) => i.size_hint(), - IntoIterInner::Int(ref i) => i.size_hint(), - IntoIterInner::Long(ref i) => i.size_hint(), - IntoIterInner::Float(ref i) => i.size_hint(), - IntoIterInner::Double(ref i) => i.size_hint(), - IntoIterInner::ByteArray(ref i) => i.size_hint(), - IntoIterInner::String(ref i) => i.size_hint(), - IntoIterInner::List(ref i) => i.size_hint(), - IntoIterInner::Compound(ref i) => i.size_hint(), - IntoIterInner::IntArray(ref i) => i.size_hint(), - IntoIterInner::LongArray(ref i) => i.size_hint(), + IntoIterInner::Byte(i) => i.size_hint(), + IntoIterInner::Short(i) => i.size_hint(), + IntoIterInner::Int(i) => i.size_hint(), + IntoIterInner::Long(i) => i.size_hint(), + IntoIterInner::Float(i) => i.size_hint(), + IntoIterInner::Double(i) => i.size_hint(), + IntoIterInner::ByteArray(i) => i.size_hint(), + IntoIterInner::String(i) => i.size_hint(), + IntoIterInner::List(i) => i.size_hint(), + IntoIterInner::Compound(i) => i.size_hint(), + IntoIterInner::IntArray(i) => i.size_hint(), + IntoIterInner::LongArray(i) => i.size_hint(), } } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { - match self.inner { + match &mut self.inner { IntoIterInner::End => None, - IntoIterInner::Byte(ref mut i) => i.next_back().map(Value::Byte), - IntoIterInner::Short(ref mut i) => i.next_back().map(Value::Short), - IntoIterInner::Int(ref mut i) => i.next_back().map(Value::Int), - IntoIterInner::Long(ref mut i) => i.next_back().map(Value::Long), - IntoIterInner::Float(ref mut i) => i.next_back().map(Value::Float), - IntoIterInner::Double(ref mut i) => i.next_back().map(Value::Double), - IntoIterInner::ByteArray(ref mut i) => i.next_back().map(Value::ByteArray), - IntoIterInner::String(ref mut i) => i.next_back().map(Value::String), - IntoIterInner::List(ref mut i) => i.next_back().map(Value::List), - IntoIterInner::Compound(ref mut i) => i.next_back().map(Value::Compound), - IntoIterInner::IntArray(ref mut i) => i.next_back().map(Value::IntArray), - IntoIterInner::LongArray(ref mut i) => i.next_back().map(Value::LongArray), + IntoIterInner::Byte(i) => i.next_back().map(Value::Byte), + IntoIterInner::Short(i) => i.next_back().map(Value::Short), + IntoIterInner::Int(i) => i.next_back().map(Value::Int), + IntoIterInner::Long(i) => i.next_back().map(Value::Long), + IntoIterInner::Float(i) => i.next_back().map(Value::Float), + IntoIterInner::Double(i) => i.next_back().map(Value::Double), + IntoIterInner::ByteArray(i) => i.next_back().map(Value::ByteArray), + IntoIterInner::String(i) => i.next_back().map(Value::String), + IntoIterInner::List(i) => i.next_back().map(Value::List), + IntoIterInner::Compound(i) => i.next_back().map(Value::Compound), + IntoIterInner::IntArray(i) => i.next_back().map(Value::IntArray), + IntoIterInner::LongArray(i) => i.next_back().map(Value::LongArray), } } } impl ExactSizeIterator for IntoIter { fn len(&self) -> usize { - match self.inner { + match &self.inner { IntoIterInner::End => 0, - IntoIterInner::Byte(ref i) => i.len(), - IntoIterInner::Short(ref i) => i.len(), - IntoIterInner::Int(ref i) => i.len(), - IntoIterInner::Long(ref i) => i.len(), - IntoIterInner::Float(ref i) => i.len(), - IntoIterInner::Double(ref i) => i.len(), - IntoIterInner::ByteArray(ref i) => i.len(), - IntoIterInner::String(ref i) => i.len(), - IntoIterInner::List(ref i) => i.len(), - IntoIterInner::Compound(ref i) => i.len(), - IntoIterInner::IntArray(ref i) => i.len(), - IntoIterInner::LongArray(ref i) => i.len(), + IntoIterInner::Byte(i) => i.len(), + IntoIterInner::Short(i) => i.len(), + IntoIterInner::Int(i) => i.len(), + IntoIterInner::Long(i) => i.len(), + IntoIterInner::Float(i) => i.len(), + IntoIterInner::Double(i) => i.len(), + IntoIterInner::ByteArray(i) => i.len(), + IntoIterInner::String(i) => i.len(), + IntoIterInner::List(i) => i.len(), + IntoIterInner::Compound(i) => i.len(), + IntoIterInner::IntArray(i) => i.len(), + IntoIterInner::LongArray(i) => i.len(), } } } @@ -765,10 +767,12 @@ impl ExactSizeIterator for IntoIter { impl FusedIterator for IntoIter {} /// The borrowing iterator type for [`List`]. +#[derive(Clone, Debug)] pub struct Iter<'a, S = String> { inner: IterInner<'a, S>, } +#[derive(Clone, Debug)] enum IterInner<'a, S> { End, Byte(std::slice::Iter<'a, i8>), @@ -789,82 +793,78 @@ impl<'a, S> Iterator for Iter<'a, S> { type Item = ValueRef<'a, S>; fn next(&mut self) -> Option { - match self.inner { + match &mut self.inner { IterInner::End => None, - IterInner::Byte(ref mut i) => i.next().map(ValueRef::Byte), - IterInner::Short(ref mut i) => i.next().map(ValueRef::Short), - IterInner::Int(ref mut i) => i.next().map(ValueRef::Int), - IterInner::Long(ref mut i) => i.next().map(ValueRef::Long), - IterInner::Float(ref mut i) => i.next().map(ValueRef::Float), - IterInner::Double(ref mut i) => i.next().map(ValueRef::Double), - IterInner::ByteArray(ref mut i) => i.next().map(|arr| ValueRef::ByteArray(&arr[..])), - IterInner::String(ref mut i) => i.next().map(ValueRef::String), - IterInner::List(ref mut i) => i.next().map(ValueRef::List), - IterInner::Compound(ref mut i) => i.next().map(ValueRef::Compound), - IterInner::IntArray(ref mut i) => i.next().map(|arr| ValueRef::IntArray(&arr[..])), - IterInner::LongArray(ref mut i) => i.next().map(|arr| ValueRef::LongArray(&arr[..])), + IterInner::Byte(i) => i.next().map(ValueRef::Byte), + IterInner::Short(i) => i.next().map(ValueRef::Short), + IterInner::Int(i) => i.next().map(ValueRef::Int), + IterInner::Long(i) => i.next().map(ValueRef::Long), + IterInner::Float(i) => i.next().map(ValueRef::Float), + IterInner::Double(i) => i.next().map(ValueRef::Double), + IterInner::ByteArray(i) => i.next().map(|arr| ValueRef::ByteArray(&arr[..])), + IterInner::String(i) => i.next().map(ValueRef::String), + IterInner::List(i) => i.next().map(ValueRef::List), + IterInner::Compound(i) => i.next().map(ValueRef::Compound), + IterInner::IntArray(i) => i.next().map(|arr| ValueRef::IntArray(&arr[..])), + IterInner::LongArray(i) => i.next().map(|arr| ValueRef::LongArray(&arr[..])), } } fn size_hint(&self) -> (usize, Option) { - match self.inner { + match &self.inner { IterInner::End => (0, Some(0)), - IterInner::Byte(ref i) => i.size_hint(), - IterInner::Short(ref i) => i.size_hint(), - IterInner::Int(ref i) => i.size_hint(), - IterInner::Long(ref i) => i.size_hint(), - IterInner::Float(ref i) => i.size_hint(), - IterInner::Double(ref i) => i.size_hint(), - IterInner::ByteArray(ref i) => i.size_hint(), - IterInner::String(ref i) => i.size_hint(), - IterInner::List(ref i) => i.size_hint(), - IterInner::Compound(ref i) => i.size_hint(), - IterInner::IntArray(ref i) => i.size_hint(), - IterInner::LongArray(ref i) => i.size_hint(), + IterInner::Byte(i) => i.size_hint(), + IterInner::Short(i) => i.size_hint(), + IterInner::Int(i) => i.size_hint(), + IterInner::Long(i) => i.size_hint(), + IterInner::Float(i) => i.size_hint(), + IterInner::Double(i) => i.size_hint(), + IterInner::ByteArray(i) => i.size_hint(), + IterInner::String(i) => i.size_hint(), + IterInner::List(i) => i.size_hint(), + IterInner::Compound(i) => i.size_hint(), + IterInner::IntArray(i) => i.size_hint(), + IterInner::LongArray(i) => i.size_hint(), } } } impl DoubleEndedIterator for Iter<'_, S> { fn next_back(&mut self) -> Option { - match self.inner { + match &mut self.inner { IterInner::End => None, - IterInner::Byte(ref mut i) => i.next_back().map(ValueRef::Byte), - IterInner::Short(ref mut i) => i.next_back().map(ValueRef::Short), - IterInner::Int(ref mut i) => i.next_back().map(ValueRef::Int), - IterInner::Long(ref mut i) => i.next_back().map(ValueRef::Long), - IterInner::Float(ref mut i) => i.next_back().map(ValueRef::Float), - IterInner::Double(ref mut i) => i.next_back().map(ValueRef::Double), - IterInner::ByteArray(ref mut i) => { - i.next_back().map(|arr| ValueRef::ByteArray(&arr[..])) - } - IterInner::String(ref mut i) => i.next_back().map(ValueRef::String), - IterInner::List(ref mut i) => i.next_back().map(ValueRef::List), - IterInner::Compound(ref mut i) => i.next_back().map(ValueRef::Compound), - IterInner::IntArray(ref mut i) => i.next_back().map(|arr| ValueRef::IntArray(&arr[..])), - IterInner::LongArray(ref mut i) => { - i.next_back().map(|arr| ValueRef::LongArray(&arr[..])) - } + IterInner::Byte(i) => i.next_back().map(ValueRef::Byte), + IterInner::Short(i) => i.next_back().map(ValueRef::Short), + IterInner::Int(i) => i.next_back().map(ValueRef::Int), + IterInner::Long(i) => i.next_back().map(ValueRef::Long), + IterInner::Float(i) => i.next_back().map(ValueRef::Float), + IterInner::Double(i) => i.next_back().map(ValueRef::Double), + IterInner::ByteArray(i) => i.next_back().map(|arr| ValueRef::ByteArray(&arr[..])), + IterInner::String(i) => i.next_back().map(ValueRef::String), + IterInner::List(i) => i.next_back().map(ValueRef::List), + IterInner::Compound(i) => i.next_back().map(ValueRef::Compound), + IterInner::IntArray(i) => i.next_back().map(|arr| ValueRef::IntArray(&arr[..])), + IterInner::LongArray(i) => i.next_back().map(|arr| ValueRef::LongArray(&arr[..])), } } } impl ExactSizeIterator for Iter<'_, S> { fn len(&self) -> usize { - match self.inner { + match &self.inner { IterInner::End => 0, - IterInner::Byte(ref i) => i.len(), - IterInner::Short(ref i) => i.len(), - IterInner::Int(ref i) => i.len(), - IterInner::Long(ref i) => i.len(), - IterInner::Float(ref i) => i.len(), - IterInner::Double(ref i) => i.len(), - IterInner::ByteArray(ref i) => i.len(), - IterInner::String(ref i) => i.len(), - IterInner::List(ref i) => i.len(), - IterInner::Compound(ref i) => i.len(), - IterInner::IntArray(ref i) => i.len(), - IterInner::LongArray(ref i) => i.len(), + IterInner::Byte(i) => i.len(), + IterInner::Short(i) => i.len(), + IterInner::Int(i) => i.len(), + IterInner::Long(i) => i.len(), + IterInner::Float(i) => i.len(), + IterInner::Double(i) => i.len(), + IterInner::ByteArray(i) => i.len(), + IterInner::String(i) => i.len(), + IterInner::List(i) => i.len(), + IterInner::Compound(i) => i.len(), + IterInner::IntArray(i) => i.len(), + IterInner::LongArray(i) => i.len(), } } } @@ -872,10 +872,12 @@ impl ExactSizeIterator for Iter<'_, S> { impl FusedIterator for Iter<'_, S> {} /// The mutable borrowing iterator type for [`List`]. +#[derive(Debug)] pub struct IterMut<'a, S = String> { inner: IterMutInner<'a, S>, } +#[derive(Debug)] enum IterMutInner<'a, S> { End, Byte(std::slice::IterMut<'a, i8>), @@ -896,78 +898,78 @@ impl<'a, S> Iterator for IterMut<'a, S> { type Item = ValueMut<'a, S>; fn next(&mut self) -> Option { - match self.inner { + match &mut self.inner { IterMutInner::End => None, - IterMutInner::Byte(ref mut i) => i.next().map(ValueMut::Byte), - IterMutInner::Short(ref mut i) => i.next().map(ValueMut::Short), - IterMutInner::Int(ref mut i) => i.next().map(ValueMut::Int), - IterMutInner::Long(ref mut i) => i.next().map(ValueMut::Long), - IterMutInner::Float(ref mut i) => i.next().map(ValueMut::Float), - IterMutInner::Double(ref mut i) => i.next().map(ValueMut::Double), - IterMutInner::ByteArray(ref mut i) => i.next().map(ValueMut::ByteArray), - IterMutInner::String(ref mut i) => i.next().map(ValueMut::String), - IterMutInner::List(ref mut i) => i.next().map(ValueMut::List), - IterMutInner::Compound(ref mut i) => i.next().map(ValueMut::Compound), - IterMutInner::IntArray(ref mut i) => i.next().map(ValueMut::IntArray), - IterMutInner::LongArray(ref mut i) => i.next().map(ValueMut::LongArray), + IterMutInner::Byte(i) => i.next().map(ValueMut::Byte), + IterMutInner::Short(i) => i.next().map(ValueMut::Short), + IterMutInner::Int(i) => i.next().map(ValueMut::Int), + IterMutInner::Long(i) => i.next().map(ValueMut::Long), + IterMutInner::Float(i) => i.next().map(ValueMut::Float), + IterMutInner::Double(i) => i.next().map(ValueMut::Double), + IterMutInner::ByteArray(i) => i.next().map(ValueMut::ByteArray), + IterMutInner::String(i) => i.next().map(ValueMut::String), + IterMutInner::List(i) => i.next().map(ValueMut::List), + IterMutInner::Compound(i) => i.next().map(ValueMut::Compound), + IterMutInner::IntArray(i) => i.next().map(ValueMut::IntArray), + IterMutInner::LongArray(i) => i.next().map(ValueMut::LongArray), } } fn size_hint(&self) -> (usize, Option) { - match self.inner { + match &self.inner { IterMutInner::End => (0, Some(0)), - IterMutInner::Byte(ref i) => i.size_hint(), - IterMutInner::Short(ref i) => i.size_hint(), - IterMutInner::Int(ref i) => i.size_hint(), - IterMutInner::Long(ref i) => i.size_hint(), - IterMutInner::Float(ref i) => i.size_hint(), - IterMutInner::Double(ref i) => i.size_hint(), - IterMutInner::ByteArray(ref i) => i.size_hint(), - IterMutInner::String(ref i) => i.size_hint(), - IterMutInner::List(ref i) => i.size_hint(), - IterMutInner::Compound(ref i) => i.size_hint(), - IterMutInner::IntArray(ref i) => i.size_hint(), - IterMutInner::LongArray(ref i) => i.size_hint(), + IterMutInner::Byte(i) => i.size_hint(), + IterMutInner::Short(i) => i.size_hint(), + IterMutInner::Int(i) => i.size_hint(), + IterMutInner::Long(i) => i.size_hint(), + IterMutInner::Float(i) => i.size_hint(), + IterMutInner::Double(i) => i.size_hint(), + IterMutInner::ByteArray(i) => i.size_hint(), + IterMutInner::String(i) => i.size_hint(), + IterMutInner::List(i) => i.size_hint(), + IterMutInner::Compound(i) => i.size_hint(), + IterMutInner::IntArray(i) => i.size_hint(), + IterMutInner::LongArray(i) => i.size_hint(), } } } impl DoubleEndedIterator for IterMut<'_, S> { fn next_back(&mut self) -> Option { - match self.inner { + match &mut self.inner { IterMutInner::End => None, - IterMutInner::Byte(ref mut i) => i.next_back().map(ValueMut::Byte), - IterMutInner::Short(ref mut i) => i.next_back().map(ValueMut::Short), - IterMutInner::Int(ref mut i) => i.next_back().map(ValueMut::Int), - IterMutInner::Long(ref mut i) => i.next_back().map(ValueMut::Long), - IterMutInner::Float(ref mut i) => i.next_back().map(ValueMut::Float), - IterMutInner::Double(ref mut i) => i.next_back().map(ValueMut::Double), - IterMutInner::ByteArray(ref mut i) => i.next_back().map(ValueMut::ByteArray), - IterMutInner::String(ref mut i) => i.next_back().map(ValueMut::String), - IterMutInner::List(ref mut i) => i.next_back().map(ValueMut::List), - IterMutInner::Compound(ref mut i) => i.next_back().map(ValueMut::Compound), - IterMutInner::IntArray(ref mut i) => i.next_back().map(ValueMut::IntArray), - IterMutInner::LongArray(ref mut i) => i.next_back().map(ValueMut::LongArray), + IterMutInner::Byte(i) => i.next_back().map(ValueMut::Byte), + IterMutInner::Short(i) => i.next_back().map(ValueMut::Short), + IterMutInner::Int(i) => i.next_back().map(ValueMut::Int), + IterMutInner::Long(i) => i.next_back().map(ValueMut::Long), + IterMutInner::Float(i) => i.next_back().map(ValueMut::Float), + IterMutInner::Double(i) => i.next_back().map(ValueMut::Double), + IterMutInner::ByteArray(i) => i.next_back().map(ValueMut::ByteArray), + IterMutInner::String(i) => i.next_back().map(ValueMut::String), + IterMutInner::List(i) => i.next_back().map(ValueMut::List), + IterMutInner::Compound(i) => i.next_back().map(ValueMut::Compound), + IterMutInner::IntArray(i) => i.next_back().map(ValueMut::IntArray), + IterMutInner::LongArray(i) => i.next_back().map(ValueMut::LongArray), } } } impl ExactSizeIterator for IterMut<'_, S> { fn len(&self) -> usize { - match self.inner { + match &self.inner { IterMutInner::End => 0, - IterMutInner::Byte(ref i) => i.len(), - IterMutInner::Short(ref i) => i.len(), - IterMutInner::Int(ref i) => i.len(), - IterMutInner::Long(ref i) => i.len(), - IterMutInner::Float(ref i) => i.len(), - IterMutInner::Double(ref i) => i.len(), - IterMutInner::ByteArray(ref i) => i.len(), - IterMutInner::String(ref i) => i.len(), - IterMutInner::List(ref i) => i.len(), - IterMutInner::Compound(ref i) => i.len(), - IterMutInner::IntArray(ref i) => i.len(), - IterMutInner::LongArray(ref i) => i.len(), + IterMutInner::Byte(i) => i.len(), + IterMutInner::Short(i) => i.len(), + IterMutInner::Int(i) => i.len(), + IterMutInner::Long(i) => i.len(), + IterMutInner::Float(i) => i.len(), + IterMutInner::Double(i) => i.len(), + IterMutInner::ByteArray(i) => i.len(), + IterMutInner::String(i) => i.len(), + IterMutInner::List(i) => i.len(), + IterMutInner::Compound(i) => i.len(), + IterMutInner::IntArray(i) => i.len(), + IterMutInner::LongArray(i) => i.len(), } } } diff --git a/old/crates/valence_nbt/src/serde.rs b/crates/valence_nbt/src/serde.rs similarity index 100% rename from old/crates/valence_nbt/src/serde.rs rename to crates/valence_nbt/src/serde.rs diff --git a/old/crates/valence_nbt/src/serde/de.rs b/crates/valence_nbt/src/serde/de.rs similarity index 98% rename from old/crates/valence_nbt/src/serde/de.rs rename to crates/valence_nbt/src/serde/de.rs index 0c5b280f1..e3826d782 100644 --- a/old/crates/valence_nbt/src/serde/de.rs +++ b/crates/valence_nbt/src/serde/de.rs @@ -37,7 +37,7 @@ where where E: de::Error, { - Ok(Value::Byte(v as _)) + Ok(Value::Byte(v.into())) } fn visit_i8(self, v: i8) -> Result @@ -72,28 +72,28 @@ where where E: de::Error, { - Ok(Value::Byte(v as _)) + Ok(Value::Byte(v as i8)) } fn visit_u16(self, v: u16) -> Result where E: de::Error, { - Ok(Value::Short(v as _)) + Ok(Value::Short(v as i16)) } fn visit_u32(self, v: u32) -> Result where E: de::Error, { - Ok(Value::Int(v as _)) + Ok(Value::Int(v as i32)) } fn visit_u64(self, v: u64) -> Result where E: de::Error, { - Ok(Value::Long(v as _)) + Ok(Value::Long(v as i64)) } fn visit_f32(self, v: f32) -> Result diff --git a/old/crates/valence_nbt/src/serde/ser.rs b/crates/valence_nbt/src/serde/ser.rs similarity index 98% rename from old/crates/valence_nbt/src/serde/ser.rs rename to crates/valence_nbt/src/serde/ser.rs index 25bfca896..516e9b5a4 100644 --- a/old/crates/valence_nbt/src/serde/ser.rs +++ b/crates/valence_nbt/src/serde/ser.rs @@ -66,6 +66,7 @@ macro_rules! unsupported { } /// [`Serializer`] whose output is [`Compound`]. +#[derive(Debug)] pub struct CompoundSerializer; impl Serializer for CompoundSerializer { @@ -267,7 +268,7 @@ impl Serializer for ValueSerializer { type SerializeStructVariant = Impossible; fn serialize_bool(self, v: bool) -> Result { - Ok(Value::Byte(v as _)) + Ok(Value::Byte(v.into())) } fn serialize_i8(self, v: i8) -> Result { @@ -287,19 +288,19 @@ impl Serializer for ValueSerializer { } fn serialize_u8(self, v: u8) -> Result { - Ok(Value::Byte(v as _)) + Ok(Value::Byte(v as i8)) } fn serialize_u16(self, v: u16) -> Result { - Ok(Value::Short(v as _)) + Ok(Value::Short(v as i16)) } fn serialize_u32(self, v: u32) -> Result { - Ok(Value::Int(v as _)) + Ok(Value::Int(v as i32)) } fn serialize_u64(self, v: u64) -> Result { - Ok(Value::Long(v as _)) + Ok(Value::Long(v as i64)) } fn serialize_f32(self, v: f32) -> Result { @@ -526,6 +527,7 @@ impl SerializeSeq for ValueSerializeSeq { } #[doc(hidden)] +#[derive(Debug)] pub struct GenericSerializeMap { /// Temp storage for `serialize_key`. key: Option, @@ -587,6 +589,7 @@ where } #[doc(hidden)] +#[derive(Debug)] pub struct GenericSerializeStruct { c: Compound, _marker: PhantomData, diff --git a/old/crates/valence_nbt/src/serde/tests.rs b/crates/valence_nbt/src/serde/tests.rs similarity index 100% rename from old/crates/valence_nbt/src/serde/tests.rs rename to crates/valence_nbt/src/serde/tests.rs diff --git a/old/crates/valence_nbt/src/snbt.rs b/crates/valence_nbt/src/snbt.rs similarity index 99% rename from old/crates/valence_nbt/src/snbt.rs rename to crates/valence_nbt/src/snbt.rs index e207da762..fbe0d634d 100644 --- a/old/crates/valence_nbt/src/snbt.rs +++ b/crates/valence_nbt/src/snbt.rs @@ -70,6 +70,7 @@ impl Error for SnbtError {} type Result = std::result::Result; +#[derive(Debug)] pub struct SnbtReader<'a> { line: usize, column: usize, @@ -444,6 +445,7 @@ pub fn from_snbt_str(snbt: &str) -> Result { SnbtReader::new(snbt).read() } +#[derive(Debug)] pub struct SnbtWriter<'a> { output: &'a mut String, } @@ -549,7 +551,7 @@ impl<'a> SnbtWriter<'a> { self.output.push('{'); let mut first = true; - for (k, v) in compound.iter() { + for (k, v) in compound { if !first { self.output.push(','); } diff --git a/old/crates/valence_nbt/src/tag.rs b/crates/valence_nbt/src/tag.rs similarity index 100% rename from old/crates/valence_nbt/src/tag.rs rename to crates/valence_nbt/src/tag.rs diff --git a/old/crates/valence_nbt/src/value.rs b/crates/valence_nbt/src/value.rs similarity index 99% rename from old/crates/valence_nbt/src/value.rs rename to crates/valence_nbt/src/value.rs index 4cb30661e..4d2d7956e 100644 --- a/old/crates/valence_nbt/src/value.rs +++ b/crates/valence_nbt/src/value.rs @@ -315,7 +315,7 @@ impl<'a, S> ValueMut<'a, S> { /// Bools are usually represented as `0` or `1` bytes in NBT. impl From for Value { fn from(b: bool) -> Self { - Value::Byte(b as _) + Value::Byte(b.into()) } } diff --git a/old/crates/valence_text/Cargo.toml b/crates/valence_text/Cargo.toml similarity index 89% rename from old/crates/valence_text/Cargo.toml rename to crates/valence_text/Cargo.toml index e1092f2ab..313a3cdd5 100644 --- a/old/crates/valence_text/Cargo.toml +++ b/crates/valence_text/Cargo.toml @@ -14,4 +14,7 @@ serde_json.workspace = true thiserror.workspace = true uuid = { workspace = true, features = ["serde"] } valence_ident.workspace = true -valence_nbt.workspace = true \ No newline at end of file +valence_nbt.workspace = true + +[lints] +workspace = true diff --git a/old/crates/valence_text/README.md b/crates/valence_text/README.md similarity index 100% rename from old/crates/valence_text/README.md rename to crates/valence_text/README.md diff --git a/old/crates/valence_text/src/color.rs b/crates/valence_text/src/color.rs similarity index 98% rename from old/crates/valence_text/src/color.rs rename to crates/valence_text/src/color.rs index c05831587..53e28821d 100644 --- a/old/crates/valence_text/src/color.rs +++ b/crates/valence_text/src/color.rs @@ -108,9 +108,9 @@ impl RgbColor { pub fn to_named_lossy(self) -> NamedColor { // calculates the squared distance between 2 colors fn squared_distance(c1: RgbColor, c2: RgbColor) -> i32 { - (c1.r as i32 - c2.r as i32).pow(2) - + (c1.g as i32 - c2.g as i32).pow(2) - + (c1.b as i32 - c2.b as i32).pow(2) + (i32::from(c1.r) - i32::from(c2.r).pow(2)) + + (i32::from(c1.g) - i32::from(c2.g)).pow(2) + + (i32::from(c1.b) - i32::from(c2.b)).pow(2) } [ @@ -297,7 +297,7 @@ impl TryFrom<&str> for RgbColor { impl Serialize for Color { fn serialize(&self, serializer: S) -> Result { - format!("{}", self).serialize(serializer) + format!("{self}").serialize(serializer) } } diff --git a/old/crates/valence_text/src/into_text.rs b/crates/valence_text/src/into_text.rs similarity index 100% rename from old/crates/valence_text/src/into_text.rs rename to crates/valence_text/src/into_text.rs diff --git a/old/crates/valence_text/src/lib.rs b/crates/valence_text/src/lib.rs similarity index 99% rename from old/crates/valence_text/src/lib.rs rename to crates/valence_text/src/lib.rs index 3c572c8ae..35650ea94 100644 --- a/old/crates/valence_text/src/lib.rs +++ b/crates/valence_text/src/lib.rs @@ -617,7 +617,7 @@ impl<'de> Deserialize<'de> for Text { } fn visit_str(self, v: &str) -> Result { - Ok(Text::text(v.to_string())) + Ok(Text::text(v.to_owned())) } fn visit_string(self, v: String) -> Result { diff --git a/old/crates/valence_text/src/tests.rs b/crates/valence_text/src/tests.rs similarity index 100% rename from old/crates/valence_text/src/tests.rs rename to crates/valence_text/src/tests.rs diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 000000000..7788221a5 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,11 @@ +edition = "2021" +unstable_features = true +wrap_comments = true +imports_granularity = "Module" +group_imports = "StdExternalCrate" +format_code_in_doc_comments = true +format_macro_matchers = true +hex_literal_case = "Lower" +format_strings = true +use_field_init_shorthand = true +use_try_shorthand = true diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 000000000..e69de29bb From 06da07c3c930407479125c47ae547559f6c4c29e Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 10 Feb 2024 12:04:36 -0800 Subject: [PATCH 03/11] Move website, extractor, and some metadata to top level --- old/CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md | 0 old/LICENSE.txt => LICENSE.txt | 0 {old/extractor => extractor}/README.md | 0 {old/extractor => extractor}/build.gradle | 0 .../copy_extractor_output.sh | 0 {old/extractor => extractor}/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {old/extractor => extractor}/gradlew | 0 {old/extractor => extractor}/gradlew.bat | 0 {old/extractor => extractor}/settings.gradle | 0 .../java/rs/valence/extractor/ClassComparator.java | 0 .../rs/valence/extractor/DummyPlayerEntity.java | 0 .../main/java/rs/valence/extractor/DummyWorld.java | 0 .../src/main/java/rs/valence/extractor/Main.java | 0 .../rs/valence/extractor/RegistryKeyComparator.java | 0 .../java/rs/valence/extractor/ValenceUtils.java | 0 .../rs/valence/extractor/extractors/Attributes.java | 0 .../rs/valence/extractor/extractors/Biomes.java | 0 .../rs/valence/extractor/extractors/Blocks.java | 0 .../java/rs/valence/extractor/extractors/Codec.java | 0 .../rs/valence/extractor/extractors/Effects.java | 0 .../rs/valence/extractor/extractors/Enchants.java | 0 .../rs/valence/extractor/extractors/Entities.java | 0 .../java/rs/valence/extractor/extractors/Items.java | 0 .../java/rs/valence/extractor/extractors/Misc.java | 0 .../rs/valence/extractor/extractors/Packets.java | 0 .../rs/valence/extractor/extractors/Sounds.java | 0 .../java/rs/valence/extractor/extractors/Tags.java | 0 .../extractor/extractors/TranslationKeys.java | 0 .../rs/valence/extractor/mixin/ExposeWallBlock.java | 0 .../src/main/resources/extractor.mixins.json | 0 .../src/main/resources/fabric.mod.json | 0 old/rustfmt.toml | 11 ----------- old/typos.toml => typos.toml | 0 {old/website => website}/.gitignore | 0 {old/website => website}/README.md | 0 {old/website => website}/book.toml | 0 .../book/1-getting-started/setup.md | 0 {old/website => website}/book/SUMMARY.md | 0 {old/website => website}/book/introduction.md | 0 {old/website => website}/build.sh | 0 {old/website => website}/config.toml | 0 {old/website => website}/content/_index.md | 0 {old/website => website}/content/faq.md | 0 {old/website => website}/content/news.md | 0 {old/website => website}/sass/_markdown.scss | 0 {old/website => website}/sass/_text.scss | 0 {old/website => website}/sass/_ultility.scss | 0 {old/website => website}/sass/juice.scss | 0 {old/website => website}/static/favicon.ico | Bin {old/website => website}/static/normalize.css | 0 {old/website => website}/static/prism.css | 0 {old/website => website}/static/prism.js | 0 {old/website => website}/static/syntax-theme.css | 0 {old/website => website}/templates/_macros.html | 0 {old/website => website}/templates/_variables.html | 0 {old/website => website}/templates/index.html | 0 {old/website => website}/templates/page.html | 0 .../templates/shortcodes/issue.html | 0 60 files changed, 11 deletions(-) rename old/CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md (100%) rename old/LICENSE.txt => LICENSE.txt (100%) rename {old/extractor => extractor}/README.md (100%) rename {old/extractor => extractor}/build.gradle (100%) rename {old/extractor => extractor}/copy_extractor_output.sh (100%) rename {old/extractor => extractor}/gradle.properties (100%) rename {old/extractor => extractor}/gradle/wrapper/gradle-wrapper.jar (100%) rename {old/extractor => extractor}/gradle/wrapper/gradle-wrapper.properties (100%) rename {old/extractor => extractor}/gradlew (100%) rename {old/extractor => extractor}/gradlew.bat (100%) rename {old/extractor => extractor}/settings.gradle (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/ClassComparator.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/DummyPlayerEntity.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/DummyWorld.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/Main.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/RegistryKeyComparator.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/ValenceUtils.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Attributes.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Biomes.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Blocks.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Codec.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Effects.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Enchants.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Entities.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Items.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Misc.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Packets.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Sounds.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/Tags.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java (100%) rename {old/extractor => extractor}/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java (100%) rename {old/extractor => extractor}/src/main/resources/extractor.mixins.json (100%) rename {old/extractor => extractor}/src/main/resources/fabric.mod.json (100%) delete mode 100644 old/rustfmt.toml rename old/typos.toml => typos.toml (100%) rename {old/website => website}/.gitignore (100%) rename {old/website => website}/README.md (100%) rename {old/website => website}/book.toml (100%) rename {old/website => website}/book/1-getting-started/setup.md (100%) rename {old/website => website}/book/SUMMARY.md (100%) rename {old/website => website}/book/introduction.md (100%) rename {old/website => website}/build.sh (100%) rename {old/website => website}/config.toml (100%) rename {old/website => website}/content/_index.md (100%) rename {old/website => website}/content/faq.md (100%) rename {old/website => website}/content/news.md (100%) rename {old/website => website}/sass/_markdown.scss (100%) rename {old/website => website}/sass/_text.scss (100%) rename {old/website => website}/sass/_ultility.scss (100%) rename {old/website => website}/sass/juice.scss (100%) rename {old/website => website}/static/favicon.ico (100%) rename {old/website => website}/static/normalize.css (100%) rename {old/website => website}/static/prism.css (100%) rename {old/website => website}/static/prism.js (100%) rename {old/website => website}/static/syntax-theme.css (100%) rename {old/website => website}/templates/_macros.html (100%) rename {old/website => website}/templates/_variables.html (100%) rename {old/website => website}/templates/index.html (100%) rename {old/website => website}/templates/page.html (100%) rename {old/website => website}/templates/shortcodes/issue.html (100%) diff --git a/old/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md similarity index 100% rename from old/CODE_OF_CONDUCT.md rename to CODE_OF_CONDUCT.md diff --git a/old/LICENSE.txt b/LICENSE.txt similarity index 100% rename from old/LICENSE.txt rename to LICENSE.txt diff --git a/old/extractor/README.md b/extractor/README.md similarity index 100% rename from old/extractor/README.md rename to extractor/README.md diff --git a/old/extractor/build.gradle b/extractor/build.gradle similarity index 100% rename from old/extractor/build.gradle rename to extractor/build.gradle diff --git a/old/extractor/copy_extractor_output.sh b/extractor/copy_extractor_output.sh similarity index 100% rename from old/extractor/copy_extractor_output.sh rename to extractor/copy_extractor_output.sh diff --git a/old/extractor/gradle.properties b/extractor/gradle.properties similarity index 100% rename from old/extractor/gradle.properties rename to extractor/gradle.properties diff --git a/old/extractor/gradle/wrapper/gradle-wrapper.jar b/extractor/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from old/extractor/gradle/wrapper/gradle-wrapper.jar rename to extractor/gradle/wrapper/gradle-wrapper.jar diff --git a/old/extractor/gradle/wrapper/gradle-wrapper.properties b/extractor/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from old/extractor/gradle/wrapper/gradle-wrapper.properties rename to extractor/gradle/wrapper/gradle-wrapper.properties diff --git a/old/extractor/gradlew b/extractor/gradlew similarity index 100% rename from old/extractor/gradlew rename to extractor/gradlew diff --git a/old/extractor/gradlew.bat b/extractor/gradlew.bat similarity index 100% rename from old/extractor/gradlew.bat rename to extractor/gradlew.bat diff --git a/old/extractor/settings.gradle b/extractor/settings.gradle similarity index 100% rename from old/extractor/settings.gradle rename to extractor/settings.gradle diff --git a/old/extractor/src/main/java/rs/valence/extractor/ClassComparator.java b/extractor/src/main/java/rs/valence/extractor/ClassComparator.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/ClassComparator.java rename to extractor/src/main/java/rs/valence/extractor/ClassComparator.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java b/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java rename to extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/DummyWorld.java b/extractor/src/main/java/rs/valence/extractor/DummyWorld.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/DummyWorld.java rename to extractor/src/main/java/rs/valence/extractor/DummyWorld.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/Main.java b/extractor/src/main/java/rs/valence/extractor/Main.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/Main.java rename to extractor/src/main/java/rs/valence/extractor/Main.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java b/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java rename to extractor/src/main/java/rs/valence/extractor/RegistryKeyComparator.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java b/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java rename to extractor/src/main/java/rs/valence/extractor/ValenceUtils.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java b/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java b/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Biomes.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java b/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java b/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Codec.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Effects.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java b/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Entities.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Items.java b/extractor/src/main/java/rs/valence/extractor/extractors/Items.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Items.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Items.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java b/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Misc.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java b/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Packets.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java b/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java b/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java rename to extractor/src/main/java/rs/valence/extractor/extractors/Tags.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java b/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java rename to extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java diff --git a/old/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java b/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java similarity index 100% rename from old/extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java rename to extractor/src/main/java/rs/valence/extractor/mixin/ExposeWallBlock.java diff --git a/old/extractor/src/main/resources/extractor.mixins.json b/extractor/src/main/resources/extractor.mixins.json similarity index 100% rename from old/extractor/src/main/resources/extractor.mixins.json rename to extractor/src/main/resources/extractor.mixins.json diff --git a/old/extractor/src/main/resources/fabric.mod.json b/extractor/src/main/resources/fabric.mod.json similarity index 100% rename from old/extractor/src/main/resources/fabric.mod.json rename to extractor/src/main/resources/fabric.mod.json diff --git a/old/rustfmt.toml b/old/rustfmt.toml deleted file mode 100644 index 7788221a5..000000000 --- a/old/rustfmt.toml +++ /dev/null @@ -1,11 +0,0 @@ -edition = "2021" -unstable_features = true -wrap_comments = true -imports_granularity = "Module" -group_imports = "StdExternalCrate" -format_code_in_doc_comments = true -format_macro_matchers = true -hex_literal_case = "Lower" -format_strings = true -use_field_init_shorthand = true -use_try_shorthand = true diff --git a/old/typos.toml b/typos.toml similarity index 100% rename from old/typos.toml rename to typos.toml diff --git a/old/website/.gitignore b/website/.gitignore similarity index 100% rename from old/website/.gitignore rename to website/.gitignore diff --git a/old/website/README.md b/website/README.md similarity index 100% rename from old/website/README.md rename to website/README.md diff --git a/old/website/book.toml b/website/book.toml similarity index 100% rename from old/website/book.toml rename to website/book.toml diff --git a/old/website/book/1-getting-started/setup.md b/website/book/1-getting-started/setup.md similarity index 100% rename from old/website/book/1-getting-started/setup.md rename to website/book/1-getting-started/setup.md diff --git a/old/website/book/SUMMARY.md b/website/book/SUMMARY.md similarity index 100% rename from old/website/book/SUMMARY.md rename to website/book/SUMMARY.md diff --git a/old/website/book/introduction.md b/website/book/introduction.md similarity index 100% rename from old/website/book/introduction.md rename to website/book/introduction.md diff --git a/old/website/build.sh b/website/build.sh similarity index 100% rename from old/website/build.sh rename to website/build.sh diff --git a/old/website/config.toml b/website/config.toml similarity index 100% rename from old/website/config.toml rename to website/config.toml diff --git a/old/website/content/_index.md b/website/content/_index.md similarity index 100% rename from old/website/content/_index.md rename to website/content/_index.md diff --git a/old/website/content/faq.md b/website/content/faq.md similarity index 100% rename from old/website/content/faq.md rename to website/content/faq.md diff --git a/old/website/content/news.md b/website/content/news.md similarity index 100% rename from old/website/content/news.md rename to website/content/news.md diff --git a/old/website/sass/_markdown.scss b/website/sass/_markdown.scss similarity index 100% rename from old/website/sass/_markdown.scss rename to website/sass/_markdown.scss diff --git a/old/website/sass/_text.scss b/website/sass/_text.scss similarity index 100% rename from old/website/sass/_text.scss rename to website/sass/_text.scss diff --git a/old/website/sass/_ultility.scss b/website/sass/_ultility.scss similarity index 100% rename from old/website/sass/_ultility.scss rename to website/sass/_ultility.scss diff --git a/old/website/sass/juice.scss b/website/sass/juice.scss similarity index 100% rename from old/website/sass/juice.scss rename to website/sass/juice.scss diff --git a/old/website/static/favicon.ico b/website/static/favicon.ico similarity index 100% rename from old/website/static/favicon.ico rename to website/static/favicon.ico diff --git a/old/website/static/normalize.css b/website/static/normalize.css similarity index 100% rename from old/website/static/normalize.css rename to website/static/normalize.css diff --git a/old/website/static/prism.css b/website/static/prism.css similarity index 100% rename from old/website/static/prism.css rename to website/static/prism.css diff --git a/old/website/static/prism.js b/website/static/prism.js similarity index 100% rename from old/website/static/prism.js rename to website/static/prism.js diff --git a/old/website/static/syntax-theme.css b/website/static/syntax-theme.css similarity index 100% rename from old/website/static/syntax-theme.css rename to website/static/syntax-theme.css diff --git a/old/website/templates/_macros.html b/website/templates/_macros.html similarity index 100% rename from old/website/templates/_macros.html rename to website/templates/_macros.html diff --git a/old/website/templates/_variables.html b/website/templates/_variables.html similarity index 100% rename from old/website/templates/_variables.html rename to website/templates/_variables.html diff --git a/old/website/templates/index.html b/website/templates/index.html similarity index 100% rename from old/website/templates/index.html rename to website/templates/index.html diff --git a/old/website/templates/page.html b/website/templates/page.html similarity index 100% rename from old/website/templates/page.html rename to website/templates/page.html diff --git a/old/website/templates/shortcodes/issue.html b/website/templates/shortcodes/issue.html similarity index 100% rename from old/website/templates/shortcodes/issue.html rename to website/templates/shortcodes/issue.html From c25c6ab1bcd4c9cf2ff7c32f8a18689816c11ad3 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 10 Feb 2024 13:10:37 -0800 Subject: [PATCH 04/11] Update extractor to 1.20.4 Changes taken from #594 Co-authored-by: Bafbi --- extractor/build.gradle | 2 +- extractor/gradle.properties | 8 ++-- extractor/gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 43462 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 +- extractor/gradlew | 35 +++++++++++------- extractor/gradlew.bat | 1 + .../java/rs/valence/extractor/DummyWorld.java | 8 +++- .../main/java/rs/valence/extractor/Main.java | 2 +- .../valence/extractor/extractors/Effects.java | 8 ++-- .../extractor/extractors/Entities.java | 11 +++--- extractor/src/main/resources/fabric.mod.json | 2 +- 11 files changed, 51 insertions(+), 30 deletions(-) diff --git a/extractor/build.gradle b/extractor/build.gradle index 3181fb394..3ea20aff0 100644 --- a/extractor/build.gradle +++ b/extractor/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.2-SNAPSHOT' + id 'fabric-loom' version '1.5-SNAPSHOT' } sourceCompatibility = JavaVersion.VERSION_17 diff --git a/extractor/gradle.properties b/extractor/gradle.properties index f75e33115..58257a494 100644 --- a/extractor/gradle.properties +++ b/extractor/gradle.properties @@ -2,12 +2,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.20.1 -yarn_mappings=1.20.1+build.1 -loader_version=0.14.21 +minecraft_version=1.20.4 +yarn_mappings=1.20.4+build.3 +loader_version=0.15.6 # Mod Properties mod_version=1.0.0 maven_group=dev.00a archives_base_name=valence-extractor # Dependencies -fabric_version=0.83.0+1.20.1 +fabric_version=0.95.0+1.20.4 diff --git a/extractor/gradle/wrapper/gradle-wrapper.jar b/extractor/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 60756 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/extractor/gradlew.bat b/extractor/gradlew.bat index 53a6b238d..6689b85be 100644 --- a/extractor/gradlew.bat +++ b/extractor/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/extractor/src/main/java/rs/valence/extractor/DummyWorld.java b/extractor/src/main/java/rs/valence/extractor/DummyWorld.java index a33bc35c1..362574c2c 100644 --- a/extractor/src/main/java/rs/valence/extractor/DummyWorld.java +++ b/extractor/src/main/java/rs/valence/extractor/DummyWorld.java @@ -30,6 +30,7 @@ import net.minecraft.world.entity.EntityLookup; import net.minecraft.world.event.GameEvent; import net.minecraft.world.tick.QueryableTickScheduler; +import net.minecraft.world.tick.TickManager; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Supplier; @@ -90,6 +91,11 @@ public Entity getEntityById(int id) { return null; } + @Override + public TickManager getTickManager() { + return null; + } + @Nullable @Override public MapState getMapState(String id) { @@ -158,7 +164,7 @@ public DynamicRegistryManager getRegistryManager() { @Override public FeatureSet getEnabledFeatures() { - return FeatureSet.of(FeatureFlags.VANILLA, FeatureFlags.BUNDLE); + return FeatureSet.of(FeatureFlags.VANILLA, FeatureFlags.BUNDLE, FeatureFlags.UPDATE_1_21); } @Override diff --git a/extractor/src/main/java/rs/valence/extractor/Main.java b/extractor/src/main/java/rs/valence/extractor/Main.java index ce183b88c..ae20fe44b 100644 --- a/extractor/src/main/java/rs/valence/extractor/Main.java +++ b/extractor/src/main/java/rs/valence/extractor/Main.java @@ -84,7 +84,7 @@ public void onInitialize() { var compound = codecExtractor.extract(); // read the compound byte-wise and write it to the file try { - NbtIo.write(compound, out.toFile()); + NbtIo.write(compound, out); } catch (IOException var3) { throw new EncoderException(var3); } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java index c89de4245..ea43d73a7 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java @@ -3,6 +3,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import net.minecraft.entity.effect.StatusEffect; import net.minecraft.registry.Registries; import rs.valence.extractor.Main; import rs.valence.extractor.ValenceUtils; @@ -35,10 +36,11 @@ public JsonElement extract() { for (var entry : effect.getAttributeModifiers().entrySet()) { var attributeModifierJson = new JsonObject(); + var attributeModidier = entry.getValue().createAttributeModifier(0); attributeModifierJson.addProperty("attribute", Registries.ATTRIBUTE.getRawId(entry.getKey())); - attributeModifierJson.addProperty("operation", entry.getValue().getOperation().getId()); - attributeModifierJson.addProperty("value", entry.getValue().getValue()); - attributeModifierJson.addProperty("uuid", entry.getValue().getId().toString()); + attributeModifierJson.addProperty("operation", attributeModidier.getOperation().getId()); + attributeModifierJson.addProperty("base_value", attributeModidier.getValue()); + attributeModifierJson.addProperty("uuid", entry.getValue().getUuid().toString()); attributeModifiersJson.add(attributeModifierJson); } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java index 172d01f25..972f84f0a 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java @@ -210,10 +210,11 @@ public JsonElement extract() throws IllegalAccessException, NoSuchFieldException // the data tracker field from the base entity class. // We also handle player entities specially since they cannot be spawned with // EntityType#create. - final var entityInstance = entityType.equals(EntityType.PLAYER) ? DummyPlayerEntity.INSTANCE + final var entityInstance = entityType.equals(EntityType.PLAYER) + ? DummyPlayerEntity.INSTANCE : entityType.create(DummyWorld.INSTANCE); - final var dataTracker = (DataTracker) dataTrackerField.get(entityInstance); + final var dataTracker = entityInstance.getDataTracker(); while (entitiesMap.get(entityClass) == null) { var entityJson = new JsonObject(); @@ -281,9 +282,9 @@ public JsonElement extract() throws IllegalAccessException, NoSuchFieldException if (bb != null && entityType != null) { var boundingBoxJson = new JsonObject(); - boundingBoxJson.addProperty("size_x", bb.getXLength()); - boundingBoxJson.addProperty("size_y", bb.getYLength()); - boundingBoxJson.addProperty("size_z", bb.getZLength()); + boundingBoxJson.addProperty("size_x", bb.getLengthX()); + boundingBoxJson.addProperty("size_y", bb.getLengthY()); + boundingBoxJson.addProperty("size_z", bb.getLengthZ()); entityJson.add("default_bounding_box", boundingBoxJson); } diff --git a/extractor/src/main/resources/fabric.mod.json b/extractor/src/main/resources/fabric.mod.json index 89a8967cb..87abfe5d5 100644 --- a/extractor/src/main/resources/fabric.mod.json +++ b/extractor/src/main/resources/fabric.mod.json @@ -22,7 +22,7 @@ ], "depends": { "fabricloader": ">=0.14.6", - "minecraft": "~1.20.1", + "minecraft": "~1.20.4", "java": ">=17" }, "suggests": { From 1791a7daa7e0216422ca507e98ec41ab475fd78f Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 10 Feb 2024 16:26:46 -0800 Subject: [PATCH 05/11] Run all extractors during SERVER_STARTING --- .../main/java/rs/valence/extractor/Main.java | 115 ++++++++---------- .../extractor/extractors/Attributes.java | 11 +- .../valence/extractor/extractors/Blocks.java | 9 +- .../valence/extractor/extractors/Codec.java | 31 ++--- .../valence/extractor/extractors/Effects.java | 9 +- .../extractor/extractors/Enchants.java | 10 +- .../extractor/extractors/Entities.java | 9 +- .../valence/extractor/extractors/Items.java | 9 +- .../rs/valence/extractor/extractors/Misc.java | 11 +- .../valence/extractor/extractors/Packets.java | 9 +- .../valence/extractor/extractors/Sounds.java | 20 +-- .../rs/valence/extractor/extractors/Tags.java | 27 ++-- .../extractor/extractors/TranslationKeys.java | 9 +- 13 files changed, 146 insertions(+), 133 deletions(-) diff --git a/extractor/src/main/java/rs/valence/extractor/Main.java b/extractor/src/main/java/rs/valence/extractor/Main.java index ae20fe44b..d620362e0 100644 --- a/extractor/src/main/java/rs/valence/extractor/Main.java +++ b/extractor/src/main/java/rs/valence/extractor/Main.java @@ -1,22 +1,26 @@ package rs.valence.extractor; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; -import io.netty.handler.codec.EncoderException; + import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.minecraft.nbt.NbtIo; +import net.minecraft.server.MinecraftServer; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rs.valence.extractor.extractors.*; import sun.reflect.ReflectionFactory; -import java.io.FileWriter; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.FileOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.charset.StandardCharsets; public class Main implements ModInitializer { public static final String MOD_ID = "valence_extractor"; @@ -38,89 +42,66 @@ public static T magicallyInstantiate(Class clazz) { @Override public void onInitialize() { - LOGGER.info("Starting extractors..."); - - var extractors = new Extractor[]{ - new Attributes(), - new Blocks(), - new Effects(), - new Enchants(), - new Entities(), - new Misc(), - new Items(), - new Packets(), - new Sounds(), - new TranslationKeys(), - }; - - Path outputDirectory; - try { - outputDirectory = Files.createDirectories(Paths.get("valence_extractor_output")); - } catch (IOException e) { - LOGGER.info("Failed to create output directory.", e); - return; - } - - var gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create(); + ServerLifecycleEvents.SERVER_STARTING.register(server -> { + LOGGER.info("Starting extractors..."); + + var extractors = new Extractor[]{ + new Attributes(), + new Blocks(), + new Effects(), + new Enchants(), + new Entities(), + new Misc(), + new Items(), + new Packets(), + new Sounds(), + new TranslationKeys(), + new Tags(), + }; - for (var ext : extractors) { + Path outputDirectory; try { - var out = outputDirectory.resolve(ext.fileName()); - var fileWriter = new FileWriter(out.toFile(), StandardCharsets.UTF_8); - gson.toJson(ext.extract(), fileWriter); - fileWriter.close(); - LOGGER.info("Wrote " + out.toAbsolutePath()); - } catch (Exception e) { - LOGGER.error("Extractor for \"" + ext.fileName() + "\" failed.", e); + outputDirectory = Files.createDirectories(Paths.get("valence_extractor_output")); + } catch (IOException e) { + LOGGER.info("Failed to create output directory.", e); + return; } - } - - ServerLifecycleEvents.SERVER_STARTING.register(server -> { - LOGGER.info("Server starting, Running startup extractors..."); - // TODO: make `Codec` implement `Extractor` - var codecExtractor = new Codec(server); - try { - var out = outputDirectory.resolve(codecExtractor.fileName()); - var compound = codecExtractor.extract(); - // read the compound byte-wise and write it to the file - try { - NbtIo.write(compound, out); - } catch (IOException var3) { - throw new EncoderException(var3); - } - LOGGER.info("Wrote " + out.toAbsolutePath()); - } catch (Exception e) { - LOGGER.error("Extractor for \"" + codecExtractor.fileName() + "\" failed.", e); - } + var gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create(); - var startupExtractors = new Extractor[]{ - new Tags(server), - }; + for (var extractor : extractors) { + var fileName = extractor.fileName(); - for (var ext : startupExtractors) { try { - var out = outputDirectory.resolve(ext.fileName()); - var fileWriter = new FileWriter(out.toFile(), StandardCharsets.UTF_8); - gson.toJson(ext.extract(), fileWriter); - fileWriter.close(); + var out = outputDirectory.resolve(fileName); + var stream = new DataOutputStream(new FileOutputStream(out.toFile())); + + extractor.extract(server, stream, gson); + + stream.close(); LOGGER.info("Wrote " + out.toAbsolutePath()); } catch (Exception e) { - LOGGER.error("Extractor for \"" + ext.fileName() + "\" failed.", e); + LOGGER.error("Extractor for \"" + fileName + "\" failed.", e); } } - LOGGER.info("Done."); + LOGGER.info("Done!"); + server.shutdown(); }); } public interface Extractor { + /** The name of the file generated by this extractor. */ String fileName(); - - JsonElement extract() throws Exception; + /** Extracts the data to the provided data output. */ + void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception; } public record Pair(T left, U right) { } + + public static void writeJson(DataOutput output, Gson gson, JsonElement element) throws IOException { + output.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8)); + } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java b/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java index c22654e9f..2da705891 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Attributes.java @@ -1,14 +1,15 @@ package rs.valence.extractor.extractors; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; +import java.io.DataOutput; + +import com.google.gson.Gson; import com.google.gson.JsonObject; import net.minecraft.entity.attribute.ClampedEntityAttribute; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; -import rs.valence.extractor.ValenceUtils; public class Attributes implements Main.Extractor { public Attributes() { @@ -20,7 +21,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception { var attributesJson = new JsonObject(); for (EntityAttribute attribute : Registries.ATTRIBUTE) { @@ -40,6 +41,6 @@ public JsonElement extract() { attributesJson.add(Registries.ATTRIBUTE.getId(attribute).getPath(), attributeJson); } - return attributesJson; + Main.writeJson(output, gson, attributesJson); } } \ No newline at end of file diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java b/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java index e2dd2fdf3..4c7b08f23 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Blocks.java @@ -1,9 +1,10 @@ package rs.valence.extractor.extractors; +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import net.minecraft.item.VerticallyAttachableBlockItem; import net.minecraft.util.math.BlockPos; import net.minecraft.world.EmptyBlockView; @@ -11,6 +12,8 @@ import rs.valence.extractor.Main; import rs.valence.extractor.mixin.ExposeWallBlock; +import java.io.DataOutput; +import java.io.IOException; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Objects; @@ -25,7 +28,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { var topLevelJson = new JsonObject(); var blocksJson = new JsonArray(); @@ -127,7 +130,7 @@ public JsonElement extract() { topLevelJson.add("shapes", shapesJson); topLevelJson.add("blocks", blocksJson); - return topLevelJson; + Main.writeJson(output, gson, topLevelJson); } private record Shape(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java b/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java index 521e2c21f..65c4888e9 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Codec.java @@ -1,8 +1,11 @@ package rs.valence.extractor.extractors; +import java.io.DataOutput; + +import com.google.gson.Gson; + import io.netty.handler.codec.EncoderException; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtOps; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.Registries; @@ -10,25 +13,23 @@ import net.minecraft.registry.SerializableRegistries; import net.minecraft.server.MinecraftServer; import net.minecraft.util.Util; +import rs.valence.extractor.Main.Extractor; -public class Codec { - - private static final RegistryOps REGISTRY_OPS= RegistryOps.of(NbtOps.INSTANCE, DynamicRegistryManager.of(Registries.REGISTRIES)); - private final DynamicRegistryManager.Immutable registryManager; - - public Codec(MinecraftServer server) { - this.registryManager = server.getRegistryManager(); - } +public class Codec implements Extractor { + @Override public String fileName() { return "registry_codec.dat"; } - public NbtCompound extract() { - com.mojang.serialization.Codec codec = SerializableRegistries.CODEC; - //DynamicRegistryManager.get(net.minecraft.registry.RegistryKey>) method. + @Override + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception { + var registryOps = RegistryOps.of(NbtOps.INSTANCE, DynamicRegistryManager.of(Registries.REGISTRIES)); + var registryManager = server.getRegistryManager(); + var codec = SerializableRegistries.CODEC; + + var nbtElement = Util.getResult(codec.encodeStart(registryOps, registryManager), (error) -> new EncoderException("Failed to encode: " + error + " " + registryManager)); - NbtElement nbtElement = Util.getResult(codec.encodeStart(REGISTRY_OPS, registryManager), (error) -> new EncoderException("Failed to encode: " + error + " " + registryManager)); - return (NbtCompound) nbtElement; + NbtIo.write(nbtElement, output); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java index ea43d73a7..dc50b6e1b 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java @@ -1,10 +1,15 @@ package rs.valence.extractor.extractors; +import java.io.DataOutput; +import java.io.IOException; + +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.entity.effect.StatusEffect; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; import rs.valence.extractor.ValenceUtils; @@ -18,7 +23,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { var effectsJson = new JsonArray(); for (var effect : Registries.STATUS_EFFECT) { @@ -52,6 +57,6 @@ public JsonElement extract() { effectsJson.add(effectJson); } - return effectsJson; + Main.writeJson(output, gson, effectsJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java b/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java index 8bf9bdb62..2235d855a 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Enchants.java @@ -1,9 +1,13 @@ package rs.valence.extractor.extractors; +import java.io.DataOutput; +import java.io.IOException; + +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; public class Enchants implements Main.Extractor { @@ -16,7 +20,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { var enchantsJson = new JsonArray(); for (var enchant : Registries.ENCHANTMENT) { @@ -42,6 +46,6 @@ public JsonElement extract() { enchantsJson.add(enchantJson); } - return enchantsJson; + Main.writeJson(output, gson, enchantsJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java index 972f84f0a..9cd6f187c 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java @@ -20,6 +20,7 @@ import net.minecraft.particle.ParticleEffect; import net.minecraft.registry.Registries; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.server.MinecraftServer; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.EulerAngle; @@ -34,6 +35,9 @@ import rs.valence.extractor.DummyWorld; import rs.valence.extractor.Main; import rs.valence.extractor.Main.Pair; + +import java.io.DataOutput; +import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.util.*; @@ -179,7 +183,8 @@ public String fileName() { @Override @SuppressWarnings("unchecked") - public JsonElement extract() throws IllegalAccessException, NoSuchFieldException { + public void extract(MinecraftServer server, DataOutput output, Gson gson) + throws IllegalAccessException, NoSuchFieldException, IOException { final var entityClassToType = new HashMap, EntityType>(); for (var f : EntityType.class.getFields()) { @@ -305,6 +310,6 @@ public JsonElement extract() throws IllegalAccessException, NoSuchFieldException entitiesJson.add(entry.getKey().getSimpleName(), entry.getValue()); } - return entitiesJson; + Main.writeJson(output, gson, entitiesJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Items.java b/extractor/src/main/java/rs/valence/extractor/extractors/Items.java index ed745badb..8e2d91281 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Items.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Items.java @@ -1,9 +1,12 @@ package rs.valence.extractor.extractors; +import java.io.DataOutput; + +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; public class Items implements Main.Extractor { @@ -16,7 +19,7 @@ public String fileName() { } @Override - public JsonElement extract() throws Exception { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception { var itemsJson = new JsonArray(); for (var item : Registries.ITEM) { @@ -61,6 +64,6 @@ public JsonElement extract() throws Exception { itemsJson.add(itemJson); } - return itemsJson; + Main.writeJson(output, gson, itemsJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java b/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java index f0dc34229..4e567cd1a 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Misc.java @@ -1,18 +1,19 @@ package rs.valence.extractor.extractors; -import com.google.gson.JsonElement; +import com.google.gson.Gson; import com.google.gson.JsonObject; import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityStatuses; -import net.minecraft.entity.attribute.ClampedEntityAttribute; -import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.data.TrackedDataHandler; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.passive.SnifferEntity; import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.Direction; import rs.valence.extractor.Main; + +import java.io.DataOutput; import java.lang.reflect.Modifier; import java.util.Locale; @@ -23,7 +24,7 @@ public String fileName() { } @Override - public JsonElement extract() throws Exception { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception { var miscJson = new JsonObject(); var entityTypeJson = new JsonObject(); @@ -130,6 +131,6 @@ public JsonElement extract() throws Exception { } miscJson.add("tracked_data_handler", trackedDataHandlerJson); - return miscJson; + Main.writeJson(output, gson, miscJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java b/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java index 9f1ae64b9..440ffcb8c 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java @@ -1,12 +1,15 @@ package rs.valence.extractor.extractors; +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.network.NetworkSide; import net.minecraft.network.NetworkState; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; +import java.io.DataOutput; +import java.io.IOException; import java.util.Locale; import java.util.TreeSet; @@ -17,7 +20,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { var packetsJson = new JsonArray(); for (var side : NetworkSide.values()) { @@ -37,6 +40,6 @@ public JsonElement extract() { } } - return packetsJson; + Main.writeJson(output, gson, packetsJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java b/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java index a204be726..34582e8fd 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Sounds.java @@ -1,9 +1,13 @@ package rs.valence.extractor.extractors; +import java.io.DataOutput; +import java.io.IOException; + +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; public class Sounds implements Main.Extractor { @@ -16,16 +20,16 @@ public String fileName() { } @Override - public JsonElement extract() throws Exception { - var itemsJson = new JsonArray(); + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { + var soundsJson = new JsonArray(); for (var sound : Registries.SOUND_EVENT) { - var itemJson = new JsonObject(); - itemJson.addProperty("id", Registries.SOUND_EVENT.getRawId(sound)); - itemJson.addProperty("name", Registries.SOUND_EVENT.getId(sound).getPath()); - itemsJson.add(itemJson); + var soundJson = new JsonObject(); + soundJson.addProperty("id", Registries.SOUND_EVENT.getRawId(sound)); + soundJson.addProperty("name", Registries.SOUND_EVENT.getId(sound).getPath()); + soundsJson.add(soundJson); } - return itemsJson; + Main.writeJson(output, gson, soundsJson); } } diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java b/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java index 2ef189144..f82116aa3 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Tags.java @@ -1,13 +1,11 @@ package rs.valence.extractor.extractors; +import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.datafixers.util.Pair; -import net.minecraft.registry.CombinedDynamicRegistries; import net.minecraft.registry.Registry; import net.minecraft.registry.SerializableRegistries; -import net.minecraft.registry.ServerDynamicRegistryType; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.server.MinecraftServer; @@ -15,15 +13,13 @@ import rs.valence.extractor.Main; import rs.valence.extractor.RegistryKeyComparator; +import java.io.DataOutput; import java.util.Map; import java.util.TreeMap; import java.util.stream.Collectors; public class Tags implements Main.Extractor { - private final CombinedDynamicRegistries dynamicRegistryManager; - - public Tags(MinecraftServer server) { - this.dynamicRegistryManager = server.getCombinedDynamicRegistries(); + public Tags() { } @Override @@ -32,15 +28,16 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws Exception { + var dynamicRegistryManager = server.getCombinedDynamicRegistries(); + var tagsJson = new JsonObject(); - final var registryTags = - SerializableRegistries.streamRegistryManagerEntries(this.dynamicRegistryManager) - .map(registry -> Pair.of(registry.key(), serializeTags(registry.value()))) - .filter(pair -> !(pair.getSecond()).isEmpty()) - .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (l, r) -> r, - () -> new TreeMap<>(new RegistryKeyComparator()))); + final var registryTags = SerializableRegistries.streamRegistryManagerEntries(dynamicRegistryManager) + .map(registry -> Pair.of(registry.key(), serializeTags(registry.value()))) + .filter(pair -> !(pair.getSecond()).isEmpty()) + .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond, (l, r) -> r, + () -> new TreeMap<>(new RegistryKeyComparator()))); for (var registry : registryTags.entrySet()) { var registryIdent = registry.getKey().getValue().toString(); @@ -55,7 +52,7 @@ public JsonElement extract() { tagsJson.add(registryIdent, tagGroupTagsJson); } - return tagsJson; + Main.writeJson(output, gson, tagsJson); } private static Map serializeTags(Registry registry) { diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java b/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java index a44ee34f0..93c54b5f2 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/TranslationKeys.java @@ -1,11 +1,16 @@ package rs.valence.extractor.extractors; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + +import net.minecraft.server.MinecraftServer; import net.minecraft.util.Language; import rs.valence.extractor.Main; +import java.io.DataOutput; +import java.io.IOException; import java.lang.reflect.Field; import java.util.Map; @@ -17,7 +22,7 @@ public String fileName() { } @Override - public JsonElement extract() { + public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { JsonArray translationsJson = new JsonArray(); Map translations = extractTranslations(); @@ -32,7 +37,7 @@ public JsonElement extract() { translationsJson.add(translationJson); } - return translationsJson; + Main.writeJson(output, gson, translationsJson); } @SuppressWarnings("unchecked") From ad3186b66f108c68346072a1aa5034e39a762b4c Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 16 Feb 2024 05:32:35 -0800 Subject: [PATCH 06/11] Rewrite entity extractor Fixed some bugs and added proper default values for fields. Partially adapted from #571. Co-authored-by: SelfMadeSystem --- .../valence/extractor/DummyPlayerEntity.java | 11 +- .../main/java/rs/valence/extractor/Main.java | 67 ++- .../rs/valence/extractor/ValenceUtils.java | 34 -- .../valence/extractor/extractors/Effects.java | 3 +- .../extractor/extractors/Entities.java | 545 +++++++++++------- 5 files changed, 393 insertions(+), 267 deletions(-) delete mode 100644 extractor/src/main/java/rs/valence/extractor/ValenceUtils.java diff --git a/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java b/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java index 9e8a4974d..b7a7d2b31 100644 --- a/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java +++ b/extractor/src/main/java/rs/valence/extractor/DummyPlayerEntity.java @@ -7,13 +7,18 @@ import net.minecraft.network.encryption.PlayerPublicKey; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; + +import java.util.UUID; + import org.jetbrains.annotations.Nullable; public class DummyPlayerEntity extends PlayerEntity { public static final DummyPlayerEntity INSTANCE; static { - INSTANCE = Main.magicallyInstantiate(DummyPlayerEntity.class); + INSTANCE = new DummyPlayerEntity(DummyWorld.INSTANCE, new BlockPos(0, 0, 0), 0, + new GameProfile(new UUID(0xDEADBEEF, 0xDEADBEEF), "dummy"), + null); try { var dataTrackerField = Entity.class.getDeclaredField("dataTracker"); @@ -21,12 +26,14 @@ public class DummyPlayerEntity extends PlayerEntity { dataTrackerField.set(INSTANCE, new DataTracker(INSTANCE)); INSTANCE.initDataTracker(); + INSTANCE.setHealth(20); // idk why player health is set to 1 by default } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); } } - private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, @Nullable PlayerPublicKey publicKey) { + private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, + @Nullable PlayerPublicKey publicKey) { super(world, pos, yaw, gameProfile); } diff --git a/extractor/src/main/java/rs/valence/extractor/Main.java b/extractor/src/main/java/rs/valence/extractor/Main.java index d620362e0..cb898e178 100644 --- a/extractor/src/main/java/rs/valence/extractor/Main.java +++ b/extractor/src/main/java/rs/valence/extractor/Main.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import net.fabricmc.api.ModInitializer; @@ -20,26 +21,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.TreeMap; import java.nio.charset.StandardCharsets; public class Main implements ModInitializer { public static final String MOD_ID = "valence_extractor"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - /** - * Magically creates an instance of a concrete class without calling its constructor. - */ - public static T magicallyInstantiate(Class clazz) { - var rf = ReflectionFactory.getReflectionFactory(); - try { - var objCon = Object.class.getDeclaredConstructor(); - var con = rf.newConstructorForSerialization(clazz, objCon); - return clazz.cast(con.newInstance()); - } catch (Throwable e) { - throw new IllegalArgumentException("Failed to magically instantiate " + clazz.getName(), e); - } - } - @Override public void onInitialize() { ServerLifecycleEvents.SERVER_STARTING.register(server -> { @@ -85,7 +73,7 @@ public void onInitialize() { } } - LOGGER.info("Done!"); + LOGGER.info("Done! Errors below this line can be ignored."); server.shutdown(); }); @@ -101,7 +89,56 @@ public interface Extractor { public record Pair(T left, U right) { } + /** + * Magically creates an instance of a concrete class without calling its constructor. + */ + public static T magicallyInstantiate(Class clazz) { + var rf = ReflectionFactory.getReflectionFactory(); + try { + var objCon = Object.class.getDeclaredConstructor(); + var con = rf.newConstructorForSerialization(clazz, objCon); + return clazz.cast(con.newInstance()); + } catch (Throwable e) { + throw new IllegalArgumentException("Failed to magically instantiate " + clazz.getName(), e); + } + } + public static void writeJson(DataOutput output, Gson gson, JsonElement element) throws IOException { output.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8)); } + + /** + * Converts a string to PascalCase. + * + * @param str The string to convert. + * @return The converted string. + */ + public static String toPascalCase(String str) { + StringBuilder result = new StringBuilder(); + boolean capitalizeNext = true; + + for (char c : str.toCharArray()) { + if (Character.isWhitespace(c) || c == '_') { + capitalizeNext = true; + } else if (capitalizeNext) { + result.append(Character.toUpperCase(c)); + capitalizeNext = false; + } else { + result.append(Character.toLowerCase(c)); + } + } + + return result.toString(); + } + + /** + * Converts a TreeMap to a JsonArray, ignoring the keys. + */ + public static JsonArray treeMapToJsonArray(TreeMap map) { + var array = new JsonArray(); + for (var value : map.values()) { + array.add(value); + } + return array; + } } diff --git a/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java b/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java deleted file mode 100644 index 847da11ab..000000000 --- a/extractor/src/main/java/rs/valence/extractor/ValenceUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package rs.valence.extractor; - -/** - * Utility class for various methods. - */ -public class ValenceUtils { - private ValenceUtils() { - throw new UnsupportedOperationException("This class cannot be instantiated"); - } - - /** - * Converts a string to PascalCase. - * - * @param str The string to convert. - * @return The converted string. - */ - public static String toPascalCase(String str) { - StringBuilder result = new StringBuilder(); - boolean capitalizeNext = true; - - for (char c : str.toCharArray()) { - if (Character.isWhitespace(c) || c == '_') { - capitalizeNext = true; - } else if (capitalizeNext) { - result.append(Character.toUpperCase(c)); - capitalizeNext = false; - } else { - result.append(Character.toLowerCase(c)); - } - } - - return result.toString(); - } -} diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java index dc50b6e1b..0c62e0fa7 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Effects.java @@ -11,7 +11,6 @@ import net.minecraft.registry.Registries; import net.minecraft.server.MinecraftServer; import rs.valence.extractor.Main; -import rs.valence.extractor.ValenceUtils; public class Effects implements Main.Extractor { public Effects() { @@ -34,7 +33,7 @@ public void extract(MinecraftServer server, DataOutput output, Gson gson) throws effectJson.addProperty("translation_key", effect.getTranslationKey()); effectJson.addProperty("color", effect.getColor()); effectJson.addProperty("instant", effect.isInstant()); - effectJson.addProperty("category", ValenceUtils.toPascalCase(effect.getCategory().name())); + effectJson.addProperty("category", Main.toPascalCase(effect.getCategory().name())); var attributeModifiersJson = new JsonArray(); diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java index 9cd6f187c..980b9c853 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java @@ -2,6 +2,7 @@ import com.google.gson.*; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityPose; @@ -12,6 +13,7 @@ import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandler; import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.passive.CatVariant; import net.minecraft.entity.passive.FrogVariant; @@ -29,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import rs.valence.extractor.ClassComparator; import rs.valence.extractor.DummyPlayerEntity; @@ -45,169 +48,49 @@ public class Entities implements Main.Extractor { public Entities() { } - private static Pair trackedDataToJson(TrackedData data, DataTracker tracker) { - final var handler = data.getType(); - final var val = tracker.get(data); - - if (handler == TrackedDataHandlerRegistry.BYTE) { - return new Pair<>("byte", new JsonPrimitive((Byte) val)); - } else if (handler == TrackedDataHandlerRegistry.INTEGER) { - return new Pair<>("integer", new JsonPrimitive((Integer) val)); - } else if (handler == TrackedDataHandlerRegistry.LONG) { - return new Pair<>("long", new JsonPrimitive((Long) val)); - } else if (handler == TrackedDataHandlerRegistry.FLOAT) { - return new Pair<>("float", new JsonPrimitive((Float) val)); - } else if (handler == TrackedDataHandlerRegistry.STRING) { - return new Pair<>("string", new JsonPrimitive((String) val)); - } else if (handler == TrackedDataHandlerRegistry.TEXT_COMPONENT) { - // TODO: return text as json element. - return new Pair<>("text_component", new JsonPrimitive(((Text) val).getString())); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_TEXT_COMPONENT) { - var res = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(((Text) o).getString())) - .orElse(JsonNull.INSTANCE); - return new Pair<>("optional_text_component", res); - } else if (handler == TrackedDataHandlerRegistry.ITEM_STACK) { - // TODO - return new Pair<>("item_stack", new JsonPrimitive(((ItemStack) val).toString())); - } else if (handler == TrackedDataHandlerRegistry.BOOLEAN) { - return new Pair<>("boolean", new JsonPrimitive((Boolean) val)); - } else if (handler == TrackedDataHandlerRegistry.ROTATION) { - var json = new JsonObject(); - var ea = (EulerAngle) val; - json.addProperty("pitch", ea.getPitch()); - json.addProperty("yaw", ea.getYaw()); - json.addProperty("roll", ea.getRoll()); - return new Pair<>("rotation", json); - } else if (handler == TrackedDataHandlerRegistry.BLOCK_POS) { - var bp = (BlockPos) val; - var json = new JsonObject(); - json.addProperty("x", bp.getX()); - json.addProperty("y", bp.getY()); - json.addProperty("z", bp.getZ()); - return new Pair<>("block_pos", json); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_BLOCK_POS) { - return new Pair<>("optional_block_pos", ((Optional) val).map(o -> { - var bp = (BlockPos) o; - var json = new JsonObject(); - json.addProperty("x", bp.getX()); - json.addProperty("y", bp.getY()); - json.addProperty("z", bp.getZ()); - return (JsonElement) json; - }).orElse(JsonNull.INSTANCE)); - } else if (handler == TrackedDataHandlerRegistry.FACING) { - return new Pair<>("facing", new JsonPrimitive(val.toString())); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_UUID) { - var res = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(o.toString())) - .orElse(JsonNull.INSTANCE); - return new Pair<>("optional_uuid", res); - } else if (handler == TrackedDataHandlerRegistry.BLOCK_STATE) { - // TODO: get raw block state ID. - var state = (BlockState) val; - return new Pair<>("block_state", new JsonPrimitive(state.toString())); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_BLOCK_STATE) { - // TODO: get raw block state ID. - var res = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(o.toString())) - .orElse(JsonNull.INSTANCE); - return new Pair<>("optional_block_state", res); - } else if (handler == TrackedDataHandlerRegistry.NBT_COMPOUND) { - // TODO: base64 binary representation or SNBT? - return new Pair<>("nbt_compound", new JsonPrimitive(val.toString())); - } else if (handler == TrackedDataHandlerRegistry.PARTICLE) { - var id = Registries.PARTICLE_TYPE.getId(((ParticleEffect) val).getType()); - return new Pair<>("particle", new JsonPrimitive(id.getPath())); - } else if (handler == TrackedDataHandlerRegistry.VILLAGER_DATA) { - var vd = (VillagerData) val; - var json = new JsonObject(); - var type = Registries.VILLAGER_TYPE.getId(vd.getType()).getPath(); - var profession = Registries.VILLAGER_PROFESSION.getId(vd.getProfession()).getPath(); - json.addProperty("type", type); - json.addProperty("profession", profession); - json.addProperty("level", vd.getLevel()); - return new Pair<>("villager_data", json); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_INT) { - var opt = (OptionalInt) val; - return new Pair<>("optional_int", opt.isPresent() ? new JsonPrimitive(opt.getAsInt()) : JsonNull.INSTANCE); - } else if (handler == TrackedDataHandlerRegistry.ENTITY_POSE) { - return new Pair<>("entity_pose", new JsonPrimitive(((EntityPose) val).name().toLowerCase(Locale.ROOT))); - } else if (handler == TrackedDataHandlerRegistry.CAT_VARIANT) { - return new Pair<>("cat_variant", - new JsonPrimitive(Registries.CAT_VARIANT.getId((CatVariant) val).getPath())); - } else if (handler == TrackedDataHandlerRegistry.FROG_VARIANT) { - return new Pair<>("frog_variant", - new JsonPrimitive(Registries.FROG_VARIANT.getId((FrogVariant) val).getPath())); - } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_GLOBAL_POS) { - return new Pair<>("optional_global_pos", ((Optional) val).map(o -> { - var gp = (GlobalPos) o; - var json = new JsonObject(); - json.addProperty("dimension", gp.getDimension().getValue().toString()); - - var posJson = new JsonObject(); - posJson.addProperty("x", gp.getPos().getX()); - posJson.addProperty("y", gp.getPos().getY()); - posJson.addProperty("z", gp.getPos().getZ()); - - json.add("position", posJson); - return (JsonElement) json; - }).orElse(JsonNull.INSTANCE)); - } else if (handler == TrackedDataHandlerRegistry.PAINTING_VARIANT) { - var variant = ((RegistryEntry) val).getKey().map(k -> k.getValue().getPath()).orElse(""); - return new Pair<>("painting_variant", new JsonPrimitive(variant)); - } else if (handler == TrackedDataHandlerRegistry.SNIFFER_STATE) { - return new Pair<>("sniffer_state", - new JsonPrimitive(((SnifferEntity.State) val).name().toLowerCase(Locale.ROOT))); - } else if (handler == TrackedDataHandlerRegistry.VECTOR3F) { - var vec = (Vector3f) val; - var json = new JsonObject(); - json.addProperty("x", vec.x); - json.addProperty("y", vec.y); - json.addProperty("z", vec.z); - return new Pair<>("vector3f", json); - } else if (handler == TrackedDataHandlerRegistry.QUATERNIONF) { - var quat = (Quaternionf) val; - var json = new JsonObject(); - json.addProperty("x", quat.x); - json.addProperty("y", quat.y); - json.addProperty("z", quat.z); - json.addProperty("w", quat.w); - return new Pair<>("quaternionf", json); - } else { - throw new IllegalArgumentException( - "Unexpected tracked handler of ID " + TrackedDataHandlerRegistry.getId(handler)); - } - } - @Override public String fileName() { return "entities.json"; } @Override - @SuppressWarnings("unchecked") public void extract(MinecraftServer server, DataOutput output, Gson gson) - throws IllegalAccessException, NoSuchFieldException, IOException { + throws IOException, IllegalAccessException, NoSuchFieldException { + var entitiesJson = new JsonObject(); - final var entityClassToType = new HashMap, EntityType>(); - for (var f : EntityType.class.getFields()) { - if (f.getType().equals(EntityType.class)) { - var entityClass = (Class) ((ParameterizedType) f.getGenericType()) - .getActualTypeArguments()[0]; - var entityType = (EntityType) f.get(null); + // Set of entity classes that have been handled. + var entitySet = new HashSet>(); - entityClassToType.put(entityClass, entityType); - } + for (var entityClass : Entities.ENTITY_CLASS_TO_TYPE_MAP.keySet()) { + Entities.handleEntity(entityClass, entitySet, entitiesJson); + } + + Main.writeJson(output, gson, entitiesJson); + } + + @SuppressWarnings("unchecked") + private static void handleEntity( + Class entityClass, + HashSet> entitySet, + JsonObject entitiesJson) throws IllegalAccessException, NoSuchFieldException { + if (entitySet.contains(entityClass)) { + // Skip if we already handled this entity. + return; } - final var dataTrackerField = Entity.class.getDeclaredField("dataTracker"); - dataTrackerField.setAccessible(true); + var entityJson = new JsonObject(); - var entitiesMap = new TreeMap, JsonElement>(new ClassComparator()); + var parentClass = entityClass.getSuperclass(); + if (parentClass != null && Entity.class.isAssignableFrom(parentClass)) { + // If the entity has a parent class, handle that too. + handleEntity((Class) parentClass, entitySet, entitiesJson); - for (var entry : entityClassToType.entrySet()) { - var entityClass = entry.getKey(); - @Nullable - var entityType = entry.getValue(); - assert entityType != null; + entityJson.addProperty("parent", parentClass.getSimpleName()); + } + var entityType = Entities.ENTITY_CLASS_TO_TYPE_MAP.get(entityClass); + // Is this a concrete entity class? + if (entityType != null) { // While we can use the tracked data registry and reflection to get the tracked // fields on entities, we won't know what their default values are because they // are assigned in the entity's constructor. @@ -215,101 +98,335 @@ public void extract(MinecraftServer server, DataOutput output, Gson gson) // the data tracker field from the base entity class. // We also handle player entities specially since they cannot be spawned with // EntityType#create. - final var entityInstance = entityType.equals(EntityType.PLAYER) + var entityInstance = entityType.equals(EntityType.PLAYER) ? DummyPlayerEntity.INSTANCE : entityType.create(DummyWorld.INSTANCE); - final var dataTracker = entityInstance.getDataTracker(); + var dataTracker = entityInstance.getDataTracker(); - while (entitiesMap.get(entityClass) == null) { - var entityJson = new JsonObject(); + var dataTrackerEntriesField = DataTracker.class.getDeclaredField("entries"); + dataTrackerEntriesField.setAccessible(true); - var parent = entityClass.getSuperclass(); - var hasParent = parent != null && Entity.class.isAssignableFrom(parent); + var dataTrackerEntries = (Int2ObjectMap>) dataTrackerEntriesField.get(dataTracker); - if (hasParent) { - entityJson.addProperty("parent", parent.getSimpleName()); - } - - if (entityType != null) { - entityJson.addProperty("type", Registries.ENTITY_TYPE.getId(entityType).getPath()); + var defaultsMap = new TreeMap(); + var defaults = (Int2ObjectMap>) dataTrackerEntriesField.get(dataTracker); - entityJson.add("translation_key", new JsonPrimitive(entityType.getTranslationKey())); - } + for (var entry : defaults.int2ObjectEntrySet()) { + var fieldJson = new JsonObject(); + var trackedData = entry.getValue().getData(); + var data = Entities.trackedDataToJson(trackedData, dataTracker); + int id = trackedData.getId(); + fieldJson.addProperty("index", id); + fieldJson.add("default_value", data.right()); + fieldJson.addProperty("type", data.left()); + defaultsMap.put(id, fieldJson); + } + entityJson.add("defaults", Main.treeMapToJsonArray(defaultsMap)); - var fieldsJson = new JsonArray(); - for (var entityField : entityClass.getDeclaredFields()) { - if (entityField.getType().equals(TrackedData.class)) { - entityField.setAccessible(true); + if (entityInstance instanceof LivingEntity livingEntity) { + var type = (EntityType) entityType; + var defaultAttributes = DefaultAttributeRegistry.get(type); + var attributesJson = new JsonArray(); + if (defaultAttributes != null) { + var instancesField = defaultAttributes.getClass().getDeclaredField("instances"); + instancesField.setAccessible(true); + var instances = (Map) instancesField + .get(defaultAttributes); - var trackedData = (TrackedData) entityField.get(null); + for (var instance : instances.values()) { + var attribute = instance.getAttribute(); - var fieldJson = new JsonObject(); - var fieldName = entityField.getName().toLowerCase(Locale.ROOT); - fieldJson.addProperty("name", fieldName); - fieldJson.addProperty("index", trackedData.getId()); + var attributeJson = new JsonObject(); - var data = Entities.trackedDataToJson(trackedData, dataTracker); - fieldJson.addProperty("type", data.left()); - fieldJson.add("default_value", data.right()); + attributeJson.addProperty("id", Registries.ATTRIBUTE.getRawId(attribute)); + attributeJson.addProperty("name", Registries.ATTRIBUTE.getId(attribute).getPath()); + attributeJson.addProperty("base_value", instance.getBaseValue()); - fieldsJson.add(fieldJson); + attributesJson.add(attributeJson); } } - entityJson.add("fields", fieldsJson); + entityJson.add("attributes", attributesJson); + } - if (entityInstance instanceof LivingEntity livingEntity) { - var type = (EntityType) entityType; - var defaultAttributes = DefaultAttributeRegistry.get(type); - var attributesJson = new JsonArray(); - if (defaultAttributes != null) { - var instancesField = defaultAttributes.getClass().getDeclaredField("instances"); - instancesField.setAccessible(true); - var instances = (Map) instancesField - .get(defaultAttributes); + var bb = entityInstance.getBoundingBox(); + if (bb != null) { + var boundingBoxJson = new JsonObject(); - for (var instance : instances.values()) { - var attribute = instance.getAttribute(); + boundingBoxJson.addProperty("size_x", bb.getLengthX()); + boundingBoxJson.addProperty("size_y", bb.getLengthY()); + boundingBoxJson.addProperty("size_z", bb.getLengthZ()); - var attributeJson = new JsonObject(); + entityJson.add("default_bounding_box", boundingBoxJson); + } + } - attributeJson.addProperty("id", Registries.ATTRIBUTE.getRawId(attribute)); - attributeJson.addProperty("name", Registries.ATTRIBUTE.getId(attribute).getPath()); - attributeJson.addProperty("base_value", instance.getBaseValue()); + var fieldsJson = new JsonArray(); + for (var entityField : entityClass.getDeclaredFields()) { + if (entityField.getType().equals(TrackedData.class)) { + entityField.setAccessible(true); - attributesJson.add(attributeJson); - } - } - entityJson.add("attributes", attributesJson); - } + var trackedData = (TrackedData) entityField.get(null); - var bb = entityInstance.getBoundingBox(); - if (bb != null && entityType != null) { - var boundingBoxJson = new JsonObject(); + var fieldJson = new JsonObject(); + var fieldName = entityField.getName().toLowerCase(Locale.ROOT); + fieldJson.addProperty("name", fieldName); + fieldJson.addProperty("index", trackedData.getId()); - boundingBoxJson.addProperty("size_x", bb.getLengthX()); - boundingBoxJson.addProperty("size_y", bb.getLengthY()); - boundingBoxJson.addProperty("size_z", bb.getLengthZ()); + // var data = Entities.trackedDataToJson(trackedData, dataTracker); + fieldJson.addProperty("type", Entities.trackedDataHandlerName(trackedData.getType())); + // fieldJson.add("default_value", data.right()); - entityJson.add("default_bounding_box", boundingBoxJson); - } + fieldsJson.add(fieldJson); + } + } + entityJson.add("fields", fieldsJson); + + entitySet.add(entityClass); + entitiesJson.add(entityClass.getSimpleName(), entityJson); + } + + private static final TreeMap, EntityType> ENTITY_CLASS_TO_TYPE_MAP = new TreeMap<>( + new ClassComparator()); + static { + for (var f : EntityType.class.getFields()) { + if (f.getType().equals(EntityType.class)) { + @SuppressWarnings("unchecked") + var entityClass = (Class) ((ParameterizedType) f.getGenericType()) + .getActualTypeArguments()[0]; - entitiesMap.put(entityClass, entityJson); + EntityType entityType; - if (!hasParent) { - break; + try { + entityType = (EntityType) f.get(null); + } catch (IllegalAccessException e) { + throw new ExceptionInInitializerError(e); } - entityClass = (Class) parent; - entityType = entityClassToType.get(entityClass); + ENTITY_CLASS_TO_TYPE_MAP.put(entityClass, entityType); } } + } - var entitiesJson = new JsonObject(); - for (var entry : entitiesMap.entrySet()) { - entitiesJson.add(entry.getKey().getSimpleName(), entry.getValue()); + private static String trackedDataHandlerName(TrackedDataHandler handler) { + if (handler == TrackedDataHandlerRegistry.BYTE) { + return "byte"; + } else if (handler == TrackedDataHandlerRegistry.INTEGER) { + return "integer"; + } else if (handler == TrackedDataHandlerRegistry.LONG) { + return "long"; + } else if (handler == TrackedDataHandlerRegistry.FLOAT) { + return "float"; + } else if (handler == TrackedDataHandlerRegistry.STRING) { + return "string"; + } else if (handler == TrackedDataHandlerRegistry.TEXT_COMPONENT) { + return "text_component"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_TEXT_COMPONENT) { + return "optional_text_component"; + } else if (handler == TrackedDataHandlerRegistry.ITEM_STACK) { + return "item_stack"; + } else if (handler == TrackedDataHandlerRegistry.BOOLEAN) { + return "boolean"; + } else if (handler == TrackedDataHandlerRegistry.ROTATION) { + return "rotation"; + } else if (handler == TrackedDataHandlerRegistry.BLOCK_POS) { + return "block_pos"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_BLOCK_POS) { + return "optional_block_pos"; + } else if (handler == TrackedDataHandlerRegistry.FACING) { + return "facing"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_UUID) { + return "optional_uuid"; + } else if (handler == TrackedDataHandlerRegistry.BLOCK_STATE) { + return "block_state"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_BLOCK_STATE) { + return "optional_block_state"; + } else if (handler == TrackedDataHandlerRegistry.NBT_COMPOUND) { + return "nbt_compound"; + } else if (handler == TrackedDataHandlerRegistry.PARTICLE) { + return "particle"; + } else if (handler == TrackedDataHandlerRegistry.VILLAGER_DATA) { + return "villager_data"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_INT) { + return "optional_int"; + } else if (handler == TrackedDataHandlerRegistry.ENTITY_POSE) { + return "entity_pose"; + } else if (handler == TrackedDataHandlerRegistry.CAT_VARIANT) { + return "cat_variant"; + } else if (handler == TrackedDataHandlerRegistry.FROG_VARIANT) { + return "frog_variant"; + } else if (handler == TrackedDataHandlerRegistry.OPTIONAL_GLOBAL_POS) { + return "optional_global_pos"; + } else if (handler == TrackedDataHandlerRegistry.PAINTING_VARIANT) { + return "painting_variant"; + } else if (handler == TrackedDataHandlerRegistry.SNIFFER_STATE) { + return "sniffer_state"; + } else if (handler == TrackedDataHandlerRegistry.VECTOR3F) { + return "vector3f"; + } else if (handler == TrackedDataHandlerRegistry.QUATERNIONF) { + return "quaternionf"; + } else { + throw new IllegalArgumentException( + "Unknown tracked data handler of ID " + TrackedDataHandlerRegistry.getId(handler)); } + } - Main.writeJson(output, gson, entitiesJson); + private static Pair trackedDataToJson(TrackedData data, DataTracker tracker) { + final var val = tracker.get(data); + + String name = trackedDataHandlerName(data.getType()); + JsonElement value = null; + + switch (name) { + case "byte": + value = new JsonPrimitive((Byte) val); + break; + case "integer": + value = new JsonPrimitive((Integer) val); + break; + case "long": + value = new JsonPrimitive((Long) val); + break; + case "float": + value = new JsonPrimitive((Float) val); + break; + case "string": + value = new JsonPrimitive((String) val); + break; + case "text_component": + // TODO: return text as json element? + value = new JsonPrimitive(((Text) val).getString()); + break; + case "optional_text_component": + value = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(((Text) o).getString())) + .orElse(JsonNull.INSTANCE); + break; + case "item_stack": + // TODO + value = new JsonPrimitive(((ItemStack) val).toString()); + break; + case "boolean": + value = new JsonPrimitive((Boolean) val); + break; + case "rotation": { + var json = new JsonObject(); + var ea = (EulerAngle) val; + json.addProperty("pitch", ea.getPitch()); + json.addProperty("yaw", ea.getYaw()); + json.addProperty("roll", ea.getRoll()); + value = json; + break; + } + case "block_pos": { + var bp = (BlockPos) val; + var json = new JsonObject(); + json.addProperty("x", bp.getX()); + json.addProperty("y", bp.getY()); + json.addProperty("z", bp.getZ()); + value = json; + break; + } + case "optional_block_pos": + value = ((Optional) val).map(o -> { + var bp = (BlockPos) o; + var json = new JsonObject(); + json.addProperty("x", bp.getX()); + json.addProperty("y", bp.getY()); + json.addProperty("z", bp.getZ()); + return (JsonElement) json; + }).orElse(JsonNull.INSTANCE); + break; + case "facing": + value = new JsonPrimitive(val.toString()); + break; + case "optional_uuid": + value = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(o.toString())) + .orElse(JsonNull.INSTANCE); + break; + case "block_state": + value = new JsonPrimitive(((BlockState) val).toString()); + break; + case "optional_block_state": + value = ((Optional) val).map(o -> (JsonElement) new JsonPrimitive(o.toString())) + .orElse(JsonNull.INSTANCE); + break; + case "nbt_compound": + // TODO: base64 binary representation or SNBT? + value = new JsonPrimitive(val.toString()); + break; + case "particle": + value = new JsonPrimitive(Registries.PARTICLE_TYPE.getId(((ParticleEffect) val).getType()).getPath()); + break; + case "villager_data": { + var vd = (VillagerData) val; + var json = new JsonObject(); + var type = Registries.VILLAGER_TYPE.getId(vd.getType()).getPath(); + var profession = Registries.VILLAGER_PROFESSION.getId(vd.getProfession()).getPath(); + json.addProperty("type", type); + json.addProperty("profession", profession); + json.addProperty("level", vd.getLevel()); + value = json; + break; + } + case "optional_int": { + var opt = (OptionalInt) val; + value = opt.isPresent() ? new JsonPrimitive(opt.getAsInt()) : JsonNull.INSTANCE; + break; + } + case "entity_pose": + value = new JsonPrimitive(((EntityPose) val).name().toLowerCase(Locale.ROOT)); + break; + case "cat_variant": + value = new JsonPrimitive(Registries.CAT_VARIANT.getId((CatVariant) val).getPath()); + break; + case "frog_variant": + value = new JsonPrimitive(Registries.FROG_VARIANT.getId((FrogVariant) val).getPath()); + break; + case "optional_global_pos": + value = ((Optional) val).map(o -> { + var gp = (GlobalPos) o; + var json = new JsonObject(); + json.addProperty("dimension", gp.getDimension().getValue().toString()); + + var posJson = new JsonObject(); + posJson.addProperty("x", gp.getPos().getX()); + posJson.addProperty("y", gp.getPos().getY()); + posJson.addProperty("z", gp.getPos().getZ()); + + json.add("position", posJson); + return (JsonElement) json; + }).orElse(JsonNull.INSTANCE); + break; + case "painting_variant": + value = new JsonPrimitive( + ((RegistryEntry) val).getKey().map(k -> k.getValue().getPath()).orElse("")); + break; + case "sniffer_state": + value = new JsonPrimitive(((SnifferEntity.State) val).name().toLowerCase(Locale.ROOT)); + break; + case "vector3f": { + var vec = (Vector3f) val; + var json = new JsonObject(); + json.addProperty("x", vec.x); + json.addProperty("y", vec.y); + json.addProperty("z", vec.z); + value = json; + break; + } + case "quaternionf": { + var quat = (Quaternionf) val; + var json = new JsonObject(); + json.addProperty("x", quat.x); + json.addProperty("y", quat.y); + json.addProperty("z", quat.z); + json.addProperty("w", quat.w); + value = json; + break; + } + default: + throw new IllegalArgumentException("Unhandled tracked data handler of type \"" + name + "\""); + } + + return new Pair<>(name, value); } } From 938997c883c2a4b39eda440459969a287f2cb47b Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 16 Feb 2024 06:07:19 -0800 Subject: [PATCH 07/11] Remove entity set in entity extractor --- .../rs/valence/extractor/extractors/Entities.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java index 980b9c853..b57a1367c 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Entities.java @@ -58,11 +58,8 @@ public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException, IllegalAccessException, NoSuchFieldException { var entitiesJson = new JsonObject(); - // Set of entity classes that have been handled. - var entitySet = new HashSet>(); - for (var entityClass : Entities.ENTITY_CLASS_TO_TYPE_MAP.keySet()) { - Entities.handleEntity(entityClass, entitySet, entitiesJson); + Entities.handleEntity(entityClass, entitiesJson); } Main.writeJson(output, gson, entitiesJson); @@ -71,11 +68,9 @@ public void extract(MinecraftServer server, DataOutput output, Gson gson) @SuppressWarnings("unchecked") private static void handleEntity( Class entityClass, - HashSet> entitySet, JsonObject entitiesJson) throws IllegalAccessException, NoSuchFieldException { - if (entitySet.contains(entityClass)) { + if (entitiesJson.get(entityClass.getSimpleName()) != null) { // Skip if we already handled this entity. - return; } var entityJson = new JsonObject(); @@ -83,7 +78,7 @@ private static void handleEntity( var parentClass = entityClass.getSuperclass(); if (parentClass != null && Entity.class.isAssignableFrom(parentClass)) { // If the entity has a parent class, handle that too. - handleEntity((Class) parentClass, entitySet, entitiesJson); + handleEntity((Class) parentClass, entitiesJson); entityJson.addProperty("parent", parentClass.getSimpleName()); } @@ -118,7 +113,7 @@ private static void handleEntity( var data = Entities.trackedDataToJson(trackedData, dataTracker); int id = trackedData.getId(); fieldJson.addProperty("index", id); - fieldJson.add("default_value", data.right()); + fieldJson.add("value", data.right()); fieldJson.addProperty("type", data.left()); defaultsMap.put(id, fieldJson); } @@ -182,7 +177,6 @@ private static void handleEntity( } entityJson.add("fields", fieldsJson); - entitySet.add(entityClass); entitiesJson.add(entityClass.getSimpleName(), entityJson); } From 92c6ce5d95e918466da2012b4e39ce9c5bb26890 Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Wed, 28 Feb 2024 04:35:44 +0000 Subject: [PATCH 08/11] Add `valence_protocol_macros` --- Cargo.toml | 2 + crates/valence_protocol_macros/Cargo.toml | 18 ++ crates/valence_protocol_macros/README.md | 3 + crates/valence_protocol_macros/src/decode.rs | 167 +++++++++++++++++++ crates/valence_protocol_macros/src/encode.rs | 165 ++++++++++++++++++ crates/valence_protocol_macros/src/lib.rs | 108 ++++++++++++ crates/valence_protocol_macros/src/packet.rs | 128 ++++++++++++++ 7 files changed, 591 insertions(+) create mode 100644 crates/valence_protocol_macros/Cargo.toml create mode 100644 crates/valence_protocol_macros/README.md create mode 100644 crates/valence_protocol_macros/src/decode.rs create mode 100644 crates/valence_protocol_macros/src/encode.rs create mode 100644 crates/valence_protocol_macros/src/lib.rs create mode 100644 crates/valence_protocol_macros/src/packet.rs diff --git a/Cargo.toml b/Cargo.toml index c066556c3..b9f63d64b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ license = "MIT" [workspace.dependencies] byteorder = "1.5.0" cesu8 = "1.1.0" +heck = "0.5.0-rc.1" indexmap = "2.2.2" java_string = { path = "crates/java_string", version = "0.1.2" } proc-macro2 = "1.0.78" @@ -45,6 +46,7 @@ thiserror = "1.0.56" uuid = "1.7.0" valence_ident = { path = "crates/valence_ident", version = "0.2.0-alpha.1" } valence_ident_macros = { path = "crates/valence_ident_macros", version = "0.2.0-alpha.1" } +valence_protocol_macros = { path = "crates/valence_protocol_macros", version = "0.2.0-alpha.1" } pretty_assertions = "1.4.0" serde_json = "1.0.113" valence_nbt = { path = "crates/valence_nbt", version = "0.8.0" } diff --git a/crates/valence_protocol_macros/Cargo.toml b/crates/valence_protocol_macros/Cargo.toml new file mode 100644 index 000000000..5f9bf9354 --- /dev/null +++ b/crates/valence_protocol_macros/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "valence_protocol_macros" +description = "Procedural macros for valence_protocol" +readme = "README.md" +version.workspace = true +edition.workspace = true +repository.workspace = true +documentation.workspace = true +license.workspace = true + +[lib] +proc-macro = true + +[dependencies] +proc-macro2.workspace = true +quote.workspace = true +syn = { workspace = true, features = ["full"] } +heck.workspace = true diff --git a/crates/valence_protocol_macros/README.md b/crates/valence_protocol_macros/README.md new file mode 100644 index 000000000..fc74027cc --- /dev/null +++ b/crates/valence_protocol_macros/README.md @@ -0,0 +1,3 @@ +# valence_protocol_macros + +Procedural macros for `valence_protocol` diff --git a/crates/valence_protocol_macros/src/decode.rs b/crates/valence_protocol_macros/src/decode.rs new file mode 100644 index 000000000..15f45e838 --- /dev/null +++ b/crates/valence_protocol_macros/src/decode.rs @@ -0,0 +1,167 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::spanned::Spanned; +use syn::{parse2, parse_quote, Data, DeriveInput, Error, Fields, Result}; + +use crate::{add_trait_bounds, decode_split_for_impl, pair_variants_with_discriminants}; + +pub(super) fn derive_decode(item: TokenStream) -> Result { + let mut input = parse2::(item)?; + + let input_name = input.ident; + + if input.generics.lifetimes().count() > 1 { + return Err(Error::new( + input.generics.params.span(), + "type deriving `Decode` must have no more than one lifetime", + )); + } + + // Use the lifetime specified in the type definition or just use `'a` if not + // present. + let lifetime = input + .generics + .lifetimes() + .next() + .map(|l| l.lifetime.clone()) + .unwrap_or_else(|| parse_quote!('a)); + + match input.data { + Data::Struct(struct_) => { + let decode_fields = match struct_.fields { + Fields::Named(fields) => { + let init = fields.named.iter().map(|f| { + let name = f.ident.as_ref().unwrap(); + let ctx = format!("failed to decode field `{name}` in `{input_name}`"); + quote! { + #name: Decode::decode(_r).context(#ctx)?, + } + }); + + quote! { + Self { + #(#init)* + } + } + } + Fields::Unnamed(fields) => { + let init = (0..fields.unnamed.len()) + .map(|i| { + let ctx = format!("failed to decode field `{i}` in `{input_name}`"); + quote! { + Decode::decode(_r).context(#ctx)?, + } + }) + .collect::(); + + quote! { + Self(#init) + } + } + Fields::Unit => quote!(Self), + }; + + add_trait_bounds( + &mut input.generics, + quote!(::valence_protocol::__private::Decode<#lifetime>), + ); + + let (impl_generics, ty_generics, where_clause) = + decode_split_for_impl(input.generics, lifetime.clone()); + + Ok(quote! { + #[allow(unused_imports)] + impl #impl_generics ::valence_protocol::__private::Decode<#lifetime> for #input_name #ty_generics + #where_clause + { + fn decode(_r: &mut &#lifetime [u8]) -> ::valence_protocol::__private::Result { + use ::valence_protocol::__private::{Decode, Context, ensure}; + + Ok(#decode_fields) + } + } + }) + } + Data::Enum(enum_) => { + let variants = pair_variants_with_discriminants(enum_.variants)?; + + let decode_arms = variants + .iter() + .map(|(disc, variant)| { + let name = &variant.ident; + + match &variant.fields { + Fields::Named(fields) => { + let fields = fields + .named + .iter() + .map(|f| { + let field = f.ident.as_ref().unwrap(); + let ctx = format!( + "failed to decode field `{field}` in variant `{name}` in \ + `{input_name}`", + ); + quote! { + #field: Decode::decode(_r).context(#ctx)?, + } + }) + .collect::(); + + quote! { + #disc => Ok(Self::#name { #fields }), + } + } + Fields::Unnamed(fields) => { + let init = (0..fields.unnamed.len()) + .map(|i| { + let ctx = format!( + "failed to decode field `{i}` in variant `{name}` in \ + `{input_name}`", + ); + quote! { + Decode::decode(_r).context(#ctx)?, + } + }) + .collect::(); + + quote! { + #disc => Ok(Self::#name(#init)), + } + } + Fields::Unit => quote!(#disc => Ok(Self::#name),), + } + }) + .collect::(); + + add_trait_bounds( + &mut input.generics, + quote!(::valence_protocol::__private::Decode<#lifetime>), + ); + + let (impl_generics, ty_generics, where_clause) = + decode_split_for_impl(input.generics, lifetime.clone()); + + Ok(quote! { + #[allow(unused_imports)] + impl #impl_generics ::valence_protocol::__private::Decode<#lifetime> for #input_name #ty_generics + #where_clause + { + fn decode(_r: &mut &#lifetime [u8]) -> ::valence_protocol::__private::Result { + use ::valence_protocol::__private::{Decode, Context, VarInt, bail}; + + let ctx = concat!("failed to decode enum discriminant in `", stringify!(#input_name), "`"); + let disc = VarInt::decode(_r).context(ctx)?.0; + match disc { + #decode_arms + n => bail!("unexpected enum discriminant {} in `{}`", disc, stringify!(#input_name)), + } + } + } + }) + } + Data::Union(u) => Err(Error::new( + u.union_token.span(), + "cannot derive `Decode` on unions", + )), + } +} diff --git a/crates/valence_protocol_macros/src/encode.rs b/crates/valence_protocol_macros/src/encode.rs new file mode 100644 index 000000000..101048e0c --- /dev/null +++ b/crates/valence_protocol_macros/src/encode.rs @@ -0,0 +1,165 @@ +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote; +use syn::spanned::Spanned; +use syn::{parse2, Data, DeriveInput, Error, Fields, LitInt, Result}; + +use crate::{add_trait_bounds, pair_variants_with_discriminants}; + +pub(super) fn derive_encode(item: TokenStream) -> Result { + let mut input = parse2::(item)?; + + let input_name = input.ident; + + add_trait_bounds( + &mut input.generics, + quote!(::valence_protocol::__private::Encode), + ); + + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + match input.data { + Data::Struct(struct_) => { + let encode_fields = match &struct_.fields { + Fields::Named(fields) => fields + .named + .iter() + .map(|f| { + let name = &f.ident.as_ref().unwrap(); + let ctx = format!("failed to encode field `{name}` in `{input_name}`"); + quote! { + self.#name.encode(&mut _w).context(#ctx)?; + } + }) + .collect(), + Fields::Unnamed(fields) => (0..fields.unnamed.len()) + .map(|i| { + let lit = LitInt::new(&i.to_string(), Span::call_site()); + let ctx = format!("failed to encode field `{lit}` in `{input_name}`"); + quote! { + self.#lit.encode(&mut _w).context(#ctx)?; + } + }) + .collect(), + Fields::Unit => TokenStream::new(), + }; + + Ok(quote! { + #[allow(unused_imports)] + impl #impl_generics ::valence_protocol::__private::Encode for #input_name #ty_generics + #where_clause + { + fn encode(&self, mut _w: impl ::std::io::Write) -> ::valence_protocol::__private::Result<()> { + use ::valence_protocol::__private::{Encode, Context}; + + #encode_fields + + Ok(()) + } + } + }) + } + Data::Enum(enum_) => { + let variants = pair_variants_with_discriminants(enum_.variants)?; + + let encode_arms = variants + .iter() + .map(|(disc, variant)| { + let variant_name = &variant.ident; + + let disc_ctx = format!( + "failed to encode enum discriminant {disc} for variant `{variant_name}` \ + in `{input_name}`", + ); + + match &variant.fields { + Fields::Named(fields) => { + let field_names = fields + .named + .iter() + .map(|f| f.ident.as_ref().unwrap()) + .collect::>(); + + let encode_fields = field_names + .iter() + .map(|name| { + let ctx = format!( + "failed to encode field `{name}` in variant \ + `{variant_name}` in `{input_name}`", + ); + + quote! { + #name.encode(&mut _w).context(#ctx)?; + } + }) + .collect::(); + + quote! { + Self::#variant_name { #(#field_names,)* } => { + VarInt(#disc).encode(&mut _w).context(#disc_ctx)?; + + #encode_fields + Ok(()) + } + } + } + Fields::Unnamed(fields) => { + let field_names = (0..fields.unnamed.len()) + .map(|i| Ident::new(&format!("_{i}"), Span::call_site())) + .collect::>(); + + let encode_fields = field_names + .iter() + .map(|name| { + let ctx = format!( + "failed to encode field `{name}` in variant \ + `{variant_name}` in `{input_name}`" + ); + + quote! { + #name.encode(&mut _w).context(#ctx)?; + } + }) + .collect::(); + + quote! { + Self::#variant_name(#(#field_names,)*) => { + VarInt(#disc).encode(&mut _w).context(#disc_ctx)?; + + #encode_fields + Ok(()) + } + } + } + Fields::Unit => quote! { + Self::#variant_name => Ok( + VarInt(#disc) + .encode(&mut _w) + .context(#disc_ctx)? + ), + }, + } + }) + .collect::(); + + Ok(quote! { + #[allow(unused_imports, unreachable_code)] + impl #impl_generics ::valence_protocol::__private::Encode for #input_name #ty_generics + #where_clause + { + fn encode(&self, mut _w: impl ::std::io::Write) -> ::valence_protocol::__private::Result<()> { + use ::valence_protocol::__private::{Encode, VarInt, Context}; + + match self { + #encode_arms + _ => unreachable!(), + } + } + } + }) + } + Data::Union(u) => Err(Error::new( + u.union_token.span(), + "cannot derive `Encode` on unions", + )), + } +} diff --git a/crates/valence_protocol_macros/src/lib.rs b/crates/valence_protocol_macros/src/lib.rs new file mode 100644 index 000000000..15ed27376 --- /dev/null +++ b/crates/valence_protocol_macros/src/lib.rs @@ -0,0 +1,108 @@ +#![doc = include_str!("../README.md")] + +use proc_macro::TokenStream as StdTokenStream; +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::{ + parse_quote, Attribute, GenericParam, Generics, Lifetime, LifetimeParam, LitInt, Result, + Variant, +}; + +mod decode; +mod encode; +mod packet; + +#[proc_macro_derive(Encode, attributes(packet))] +pub fn derive_encode(item: StdTokenStream) -> StdTokenStream { + match encode::derive_encode(item.into()) { + Ok(tokens) => tokens.into(), + Err(e) => e.into_compile_error().into(), + } +} + +#[proc_macro_derive(Decode, attributes(packet))] +pub fn derive_decode(item: StdTokenStream) -> StdTokenStream { + match decode::derive_decode(item.into()) { + Ok(tokens) => tokens.into(), + Err(e) => e.into_compile_error().into(), + } +} + +#[proc_macro_derive(Packet, attributes(packet))] +pub fn derive_packet(item: StdTokenStream) -> StdTokenStream { + match packet::derive_packet(item.into()) { + Ok(tokens) => tokens.into(), + Err(e) => e.into_compile_error().into(), + } +} + +fn pair_variants_with_discriminants( + variants: impl IntoIterator, +) -> Result> { + let mut discriminant = 0; + variants + .into_iter() + .map(|v| { + if let Some(i) = parse_tag_attr(&v.attrs)? { + discriminant = i; + } + + let pair = (discriminant, v); + discriminant += 1; + Ok(pair) + }) + .collect::>() +} + +fn parse_tag_attr(attrs: &[Attribute]) -> Result> { + for attr in attrs { + if attr.path().is_ident("packet") { + let mut res = 0; + + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("tag") { + res = meta.value()?.parse::()?.base10_parse::()?; + Ok(()) + } else { + Err(meta.error("unrecognized argument")) + } + })?; + + return Ok(Some(res)); + } + } + + Ok(None) +} + +/// Adding our lifetime to the generics before calling `.split_for_impl()` would +/// also add it to the resulting ty_generics, which we don't want. So I'm doing +/// this hack. +fn decode_split_for_impl( + mut generics: Generics, + lifetime: Lifetime, +) -> (TokenStream, TokenStream, TokenStream) { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let mut impl_generics = impl_generics.to_token_stream(); + let ty_generics = ty_generics.to_token_stream(); + let where_clause = where_clause.to_token_stream(); + + if generics.lifetimes().next().is_none() { + generics + .params + .push(GenericParam::Lifetime(LifetimeParam::new(lifetime))); + + impl_generics = generics.split_for_impl().0.to_token_stream(); + } + + (impl_generics, ty_generics, where_clause) +} + +fn add_trait_bounds(generics: &mut Generics, trait_: TokenStream) { + for param in &mut generics.params { + if let GenericParam::Type(type_param) = param { + type_param.bounds.push(parse_quote!(#trait_)) + } + } +} diff --git a/crates/valence_protocol_macros/src/packet.rs b/crates/valence_protocol_macros/src/packet.rs new file mode 100644 index 000000000..9d2cdd559 --- /dev/null +++ b/crates/valence_protocol_macros/src/packet.rs @@ -0,0 +1,128 @@ +use heck::ToShoutySnakeCase; +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote; +use syn::spanned::Spanned; +use syn::{parse2, parse_quote, Attribute, DeriveInput, Error, Expr, LitInt, LitStr, Result}; + +use crate::add_trait_bounds; + +pub(super) fn derive_packet(item: TokenStream) -> Result { + let mut input = parse2::(item)?; + + let packet_attr = parse_packet_helper_attr(&input.attrs)?.unwrap_or_default(); + + let name = input.ident.clone(); + + let name_str = if let Some(attr_name) = packet_attr.name { + attr_name.value() + } else { + name.to_string() + }; + + let packet_id: Expr = match packet_attr.id { + Some(expr) => expr, + None => match syn::parse_str::(&name_str.to_shouty_snake_case()) { + Ok(ident) => parse_quote!(::valence_protocol::packet_id::#ident), + Err(_) => { + return Err(Error::new( + packet_attr.span, + "missing valid `id = ...` value from `packet` attr", + )) + } + }, + }; + + add_trait_bounds(&mut input.generics, quote!(::std::fmt::Debug)); + + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let side = if let Some(side_attr) = packet_attr.side { + side_attr + } else if name_str.to_lowercase().ends_with("s2c") { + parse_quote!(::valence_protocol::PacketSide::Clientbound) + } else if name_str.to_lowercase().ends_with("c2s") { + parse_quote!(::valence_protocol::PacketSide::Serverbound) + } else { + return Err(Error::new( + packet_attr.span, + "missing `side = PacketSide::...` value from `packet` attribute", + )); + }; + + let state = packet_attr + .state + .unwrap_or_else(|| parse_quote!(::valence_protocol::PacketState::Play)); + + Ok(quote! { + impl #impl_generics ::valence_protocol::__private::Packet for #name #ty_generics + #where_clause + { + const ID: i32 = #packet_id; + const NAME: &'static str = #name_str; + const SIDE: ::valence_protocol::PacketSide = #side; + const STATE: ::valence_protocol::PacketState = #state; + } + }) +} + +struct PacketAttr { + span: Span, + id: Option, + tag: Option, + name: Option, + side: Option, + state: Option, +} + +impl Default for PacketAttr { + fn default() -> Self { + Self { + span: Span::call_site(), + id: Default::default(), + tag: Default::default(), + name: Default::default(), + side: Default::default(), + state: Default::default(), + } + } +} + +fn parse_packet_helper_attr(attrs: &[Attribute]) -> Result> { + for attr in attrs { + if attr.path().is_ident("packet") { + let mut res = PacketAttr { + span: attr.span(), + id: None, + tag: None, + name: None, + side: None, + state: None, + }; + + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("id") { + res.id = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("tag") { + res.tag = Some(meta.value()?.parse::()?.base10_parse::()?); + Ok(()) + } else if meta.path.is_ident("name") { + res.name = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("side") { + res.side = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("state") { + res.state = Some(meta.value()?.parse::()?); + Ok(()) + } else { + Err(meta.error("unrecognized packet argument")) + } + })?; + + return Ok(Some(res)); + } + } + + Ok(None) +} From 7af6000b808aa149c31290253def4f3781c9002f Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Sat, 2 Mar 2024 04:49:44 +0000 Subject: [PATCH 09/11] Setup valence_protocol --- Cargo.toml | 34 +- crates/valence_build_utils/Cargo.toml | 14 + crates/valence_build_utils/README.md | 3 + crates/valence_build_utils/src/lib.rs | 74 + crates/valence_math/Cargo.toml | 12 + crates/valence_math/README.md | 6 + crates/valence_math/src/aabb.rs | 214 +++ crates/valence_math/src/lib.rs | 6 + crates/valence_protocol/Cargo.toml | 50 + crates/valence_protocol/build.rs | 53 + .../valence_protocol/extracted/packets.json | 1214 +++++++++++++++++ crates/valence_protocol/src/lib.rs | 197 +++ crates/valence_protocol/src/packets.rs | 49 + .../src/packets/handshake_c2s.rs | 43 + .../src/packets/ping_result_s2c.rs | 24 + .../src/packets/query_ping_c2s.rs | 24 + .../src/packets/query_request_c2s.rs | 20 + .../src/packets/query_response_s2c.rs | 24 + crates/valence_protocol/src/var_int.rs | 97 ++ crates/valence_protocol_macros/src/packet.rs | 208 +-- extractor/copy_extractor_output.sh | 11 +- .../valence/extractor/extractors/Packets.java | 6 +- rustfmt.toml | 2 +- 23 files changed, 2271 insertions(+), 114 deletions(-) create mode 100644 crates/valence_build_utils/Cargo.toml create mode 100644 crates/valence_build_utils/README.md create mode 100644 crates/valence_build_utils/src/lib.rs create mode 100644 crates/valence_math/Cargo.toml create mode 100644 crates/valence_math/README.md create mode 100644 crates/valence_math/src/aabb.rs create mode 100644 crates/valence_math/src/lib.rs create mode 100644 crates/valence_protocol/Cargo.toml create mode 100644 crates/valence_protocol/build.rs create mode 100644 crates/valence_protocol/extracted/packets.json create mode 100644 crates/valence_protocol/src/lib.rs create mode 100644 crates/valence_protocol/src/packets.rs create mode 100644 crates/valence_protocol/src/packets/handshake_c2s.rs create mode 100644 crates/valence_protocol/src/packets/ping_result_s2c.rs create mode 100644 crates/valence_protocol/src/packets/query_ping_c2s.rs create mode 100644 crates/valence_protocol/src/packets/query_request_c2s.rs create mode 100644 crates/valence_protocol/src/packets/query_response_s2c.rs create mode 100644 crates/valence_protocol/src/var_int.rs diff --git a/Cargo.toml b/Cargo.toml index b9f63d64b..85d9cf48e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,13 @@ categories = ["game-engines"] [lints] workspace = true +[dependencies] +anyhow.workspace = true +evenio = { path = "/home/rj/dev/evenio", version = "0.3.0" } +monoio.workspace = true +uuid.workspace = true +serde = { workspace = true, features = ["derive"] } + #### WORKSPACE #### [profile.dev.package."*"] @@ -26,30 +33,49 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.2.0-alpha.1+mc.1.20.1" +version = "0.2.0-alpha.1+mc.1.20.4" edition = "2021" repository = "https://github.com/valence-rs/valence" documentation = "https://docs.rs/valence/" license = "MIT" [workspace.dependencies] +aes = "0.8.4" +anyhow = "1.0.80" +base64 = "0.21.7" +bitfield-struct = "0.6.0" byteorder = "1.5.0" +bytes = "1.5.0" cesu8 = "1.1.0" +cfb8 = "0.8.1" +derive_more = "1.0.0-beta.6" +flate2 = "1.0.28" +glam = "0.25.0" heck = "0.5.0-rc.1" indexmap = "2.2.2" java_string = { path = "crates/java_string", version = "0.1.2" } +monoio = "0.2.2" +num-derive = "0.4.2" +num-traits = "0.2.18" +pretty_assertions = "1.4.0" proc-macro2 = "1.0.78" quote = "1.0.35" +rand = "0.8.5" serde = "1.0.196" +serde_json = "1.0.113" syn = { version = "2.0.48", features = ["full"] } thiserror = "1.0.56" +url = { version = "2.5.0", features = ["serde"] } uuid = "1.7.0" +valence_build_utils = { path = "crates/valence_build_utils", version = "0.2.0-alpha.1" } +# valence_generated = { path = "crates/valence_generated", version = "0.2.0-alpha.1" } valence_ident = { path = "crates/valence_ident", version = "0.2.0-alpha.1" } valence_ident_macros = { path = "crates/valence_ident_macros", version = "0.2.0-alpha.1" } -valence_protocol_macros = { path = "crates/valence_protocol_macros", version = "0.2.0-alpha.1" } -pretty_assertions = "1.4.0" -serde_json = "1.0.113" +valence_math = { path = "crates/valence_math", version = "0.2.0-alpha.1" } valence_nbt = { path = "crates/valence_nbt", version = "0.8.0" } +valence_protocol = { path = "crates/valence_protocol", version = "0.2.0-alpha.1" } +valence_protocol_macros = { path = "crates/valence_protocol_macros", version = "0.2.0-alpha.1" } +valence_text = { path = "crates/valence_text", version = "0.2.0-alpha.1" } [workspace.lints.rust] elided_lifetimes_in_paths = "allow" # Warned by `future_incompatible`. diff --git a/crates/valence_build_utils/Cargo.toml b/crates/valence_build_utils/Cargo.toml new file mode 100644 index 000000000..7a928faaf --- /dev/null +++ b/crates/valence_build_utils/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "valence_build_utils" +description = "Common build script utilities for Valence" +readme = "README.md" +version.workspace = true +edition.workspace = true +repository.workspace = true +documentation.workspace = true +license.workspace = true + +[dependencies] +anyhow.workspace = true +syn.workspace = true +proc-macro2.workspace = true diff --git a/crates/valence_build_utils/README.md b/crates/valence_build_utils/README.md new file mode 100644 index 000000000..fa275e1a7 --- /dev/null +++ b/crates/valence_build_utils/README.md @@ -0,0 +1,3 @@ +# valence_build_utils + +Common code used in build scripts. diff --git a/crates/valence_build_utils/src/lib.rs b/crates/valence_build_utils/src/lib.rs new file mode 100644 index 000000000..2128625d6 --- /dev/null +++ b/crates/valence_build_utils/src/lib.rs @@ -0,0 +1,74 @@ +#![doc = include_str!("../README.md")] +#![deny( + rustdoc::broken_intra_doc_links, + rustdoc::private_intra_doc_links, + rustdoc::missing_crate_level_docs, + rustdoc::invalid_codeblock_attributes, + rustdoc::invalid_rust_codeblocks, + rustdoc::bare_urls, + rustdoc::invalid_html_tags +)] +#![warn( + trivial_casts, + trivial_numeric_casts, + unused_lifetimes, + unused_import_braces, + unreachable_pub, + clippy::dbg_macro +)] + +use std::path::Path; +use std::process::Command; +use std::{env, fs}; + +use anyhow::Context; +use proc_macro2::{Ident, Span, TokenStream}; + +/// Write a Rust file to the build script output directory. The file is formatted if `rustfmt` is available. +/// +/// To include the file outside the build script, use +/// +/// ```ignore +/// include!(concat!(env!("OUT_DIR"), "/name_of_the_file.rs")); +/// ```` +/// Where `name_of_the_file.rs` is the value of `out_file`. +pub fn write_generated_file(content: TokenStream, out_file: &str) -> anyhow::Result<()> { + let out_dir = env::var_os("OUT_DIR").context("failed to get OUT_DIR env var")?; + let path = Path::new(&out_dir).join(out_file); + let code = content.to_string(); + + fs::write(&path, code)?; + + // Try to format the output for debugging purposes. + // Doesn't matter if rustfmt is unavailable. + let _ = Command::new("rustfmt").arg(path).output(); + + Ok(()) +} + +/// Parses a [`proc_macro2::Ident`] from a `str`. Rust keywords are prepended +/// with underscores to make them valid identifiers. +/// +/// # Panics +/// +/// Panics if a valid identifier could not be formed. +pub fn ident(s: impl AsRef) -> Ident { + let s = s.as_ref().trim(); + + // Parse the ident from a str. If the string is a Rust keyword, stick an + // underscore in front. + syn::parse_str::(s) + .unwrap_or_else(|_| Ident::new(format!("_{s}").as_str(), Span::call_site())) +} + +#[track_caller] +pub fn rerun_if_changed(files: [&str; N]) { + for file in files { + assert!( + Path::new(file).exists(), + "File \"{file}\" does not exist. Did you forget to update the path?" + ); + + println!("cargo:rerun-if-changed={file}"); + } +} diff --git a/crates/valence_math/Cargo.toml b/crates/valence_math/Cargo.toml new file mode 100644 index 000000000..08badf18c --- /dev/null +++ b/crates/valence_math/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "valence_math" +description = "Math for Valence" +readme = "README.md" +version.workspace = true +edition.workspace = true +repository.workspace = true +documentation.workspace = true +license.workspace = true + +[dependencies] +glam.workspace = true diff --git a/crates/valence_math/README.md b/crates/valence_math/README.md new file mode 100644 index 000000000..d7f7f9189 --- /dev/null +++ b/crates/valence_math/README.md @@ -0,0 +1,6 @@ +# valence_math + +Common math utilities for Valence. + +This crate re-exports the contents of [`glam`](https://docs.rs/glam/latest/glam/) along with our own types such as [`Aabb`]. +For more information, please see `glam`'s documentation. diff --git a/crates/valence_math/src/aabb.rs b/crates/valence_math/src/aabb.rs new file mode 100644 index 000000000..48b02e2f7 --- /dev/null +++ b/crates/valence_math/src/aabb.rs @@ -0,0 +1,214 @@ +use std::ops::{Add, Sub}; + +use glam::DVec3; + +/// A three-dimensional axis-aligned bounding box, or "AABB". +/// +/// The AABB is defined by two points—`min` and `max`. `min` is less than or +/// equal to `max` componentwise. +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub struct Aabb { + min: DVec3, + max: DVec3, +} + +impl Aabb { + pub const ZERO: Self = Self { + min: DVec3::ZERO, + max: DVec3::ZERO, + }; + + /// Constructs a new AABB from `min` and `max` points. + /// + /// # Panics + /// + /// Panics if `debug_assertions` are enabled and `min` is not less than or + /// equal to `max` componentwise. + #[cfg_attr(debug_assertions, track_caller)] + pub fn new(min: DVec3, max: DVec3) -> Self { + debug_assert!( + min.x <= max.x && min.y <= max.y && min.z <= max.z, + "`min` must be less than or equal to `max` componentwise (min = {min}, max = {max})" + ); + + Self { min, max } + } + + // TODO: remove when the assertion in `new` can be done in a `const` context. + #[doc(hidden)] + pub const fn new_unchecked(min: DVec3, max: DVec3) -> Self { + Self { min, max } + } + + /// Returns a new AABB containing a single point `p`. + pub fn new_point(p: DVec3) -> Self { + Self::new(p, p) + } + + pub fn from_bottom_size(bottom: DVec3, size: DVec3) -> Self { + Self::new( + DVec3 { + x: bottom.x - size.x / 2.0, + y: bottom.y, + z: bottom.z - size.z / 2.0, + }, + DVec3 { + x: bottom.x + size.x / 2.0, + y: bottom.y + size.y, + z: bottom.z + size.z / 2.0, + }, + ) + } + + pub const fn min(self) -> DVec3 { + self.min + } + + pub const fn max(self) -> DVec3 { + self.max + } + + pub fn union(self, other: Self) -> Self { + Self::new(self.min.min(other.min), self.max.max(other.max)) + } + + pub fn intersects(self, other: Self) -> bool { + self.max.x >= other.min.x + && other.max.x >= self.min.x + && self.max.y >= other.min.y + && other.max.y >= self.min.y + && self.max.z >= other.min.z + && other.max.z >= self.min.z + } + + /// Does this bounding box contain the given point? + pub fn contains_point(self, p: DVec3) -> bool { + self.min.x <= p.x + && self.min.y <= p.y + && self.min.z <= p.z + && self.max.x >= p.x + && self.max.y >= p.y + && self.max.z >= p.z + } + + /// Returns the closest point in the AABB to the given point. + pub fn projected_point(self, p: DVec3) -> DVec3 { + p.clamp(self.min, self.max) + } + + /// Returns the smallest distance from the AABB to the point. + pub fn distance_to_point(self, p: DVec3) -> f64 { + self.projected_point(p).distance(p) + } + + /// Calculates the intersection between this AABB and a ray + /// defined by its `origin` point and `direction` vector. + /// + /// If an intersection occurs, `Some([near, far])` is returned. `near` and + /// `far` are the values of `t` in the equation `origin + t * direction = + /// point` where `point` is the nearest or furthest intersection point to + /// the `origin`. If no intersection occurs, then `None` is returned. + /// + /// In other words, if `direction` is normalized, then `near` and `far` are + /// the distances to the nearest and furthest intersection points. + pub fn ray_intersection(self, origin: DVec3, direction: DVec3) -> Option<[f64; 2]> { + let mut near: f64 = 0.0; + let mut far = f64::INFINITY; + + for i in 0..3 { + // Rust's definition of `min` and `max` properly handle the NaNs these + // computations may produce. + let t0 = (self.min[i] - origin[i]) / direction[i]; + let t1 = (self.max[i] - origin[i]) / direction[i]; + + near = near.max(t0.min(t1)); + far = far.min(t0.max(t1)); + } + + if near <= far { + Some([near, far]) + } else { + None + } + } +} + +impl Add for Aabb { + type Output = Aabb; + + fn add(self, rhs: DVec3) -> Self::Output { + Self::new(self.min + rhs, self.max + rhs) + } +} + +impl Add for DVec3 { + type Output = Aabb; + + fn add(self, rhs: Aabb) -> Self::Output { + rhs + self + } +} + +impl Sub for Aabb { + type Output = Aabb; + + fn sub(self, rhs: DVec3) -> Self::Output { + Self::new(self.min - rhs, self.max - rhs) + } +} + +impl Sub for DVec3 { + type Output = Aabb; + + fn sub(self, rhs: Aabb) -> Self::Output { + rhs - self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ray_intersect_edge_cases() { + let bb = Aabb::new([0.0, 0.0, 0.0].into(), [1.0, 1.0, 1.0].into()); + + let ros = [ + // On a corner + DVec3::new(0.0, 0.0, 0.0), + // Outside + DVec3::new(-0.5, 0.5, -0.5), + // In the center + DVec3::new(0.5, 0.5, 0.5), + // On an edge + DVec3::new(0.0, 0.5, 0.0), + // On a face + DVec3::new(0.0, 0.5, 0.5), + // Outside slabs + DVec3::new(-2.0, -2.0, -2.0), + ]; + + let rds = [ + DVec3::new(1.0, 0.0, 0.0), + DVec3::new(-1.0, 0.0, 0.0), + DVec3::new(0.0, 1.0, 0.0), + DVec3::new(0.0, -1.0, 0.0), + DVec3::new(0.0, 0.0, 1.0), + DVec3::new(0.0, 0.0, -1.0), + ]; + + assert!(rds.iter().all(|d| d.is_normalized())); + + for ro in ros { + for rd in rds { + if let Some([near, far]) = bb.ray_intersection(ro, rd) { + assert!(near.is_finite()); + assert!(far.is_finite()); + assert!(near <= far); + assert!(near >= 0.0); + assert!(far >= 0.0); + } + } + } + } +} diff --git a/crates/valence_math/src/lib.rs b/crates/valence_math/src/lib.rs new file mode 100644 index 000000000..bf3db2c01 --- /dev/null +++ b/crates/valence_math/src/lib.rs @@ -0,0 +1,6 @@ +#![doc = include_str!("../README.md")] + +mod aabb; + +pub use aabb::Aabb; +pub use glam::*; diff --git a/crates/valence_protocol/Cargo.toml b/crates/valence_protocol/Cargo.toml new file mode 100644 index 000000000..a2be4c5a1 --- /dev/null +++ b/crates/valence_protocol/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "valence_protocol" +description = "Protocol library for Minecraft: Java Edition" +readme = "README.md" +version.workspace = true +edition.workspace = true +repository.workspace = true +documentation.workspace = true +license.workspace = true + +[features] +encryption = ["dep:aes", "dep:cfb8"] +compression = ["dep:flate2"] + +[dependencies] +valence_math.workspace = true +# valence_generated.workspace = true +valence_text.workspace = true +valence_nbt = { workspace = true, features = ["binary"] } +valence_protocol_macros.workspace = true +anyhow.workspace = true +thiserror.workspace = true +serde = { workspace = true, features = ["derive"] } +# byteorder.workspace = true +uuid.workspace = true +valence_ident.workspace = true +base64.workspace = true +url.workspace = true +serde_json.workspace = true +# tracing.workspace = true +bytes.workspace = true +bitfield-struct.workspace = true +# derive_more = { workspace = true, features = ["try_from", "from", "into", "deref", "deref_mut", "as_ref"] } +num-derive.workspace = true +num-traits.workspace = true +cfb8 = { workspace = true, optional = true } +flate2 = { workspace = true, optional = true } +aes = { workspace = true, optional = true } + +[dev-dependencies] +rand.workspace = true + +[build-dependencies] +valence_build_utils.workspace = true +heck.workspace = true +proc-macro2.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +quote.workspace = true +anyhow.workspace = true \ No newline at end of file diff --git a/crates/valence_protocol/build.rs b/crates/valence_protocol/build.rs new file mode 100644 index 000000000..c5852ed07 --- /dev/null +++ b/crates/valence_protocol/build.rs @@ -0,0 +1,53 @@ +use std::collections::BTreeMap; + +use heck::ToShoutySnakeCase; +use proc_macro2::TokenStream; +use quote::quote; +use serde::Deserialize; +use valence_build_utils::{ident, rerun_if_changed, write_generated_file}; + +#[derive(Deserialize)] +struct Packet { + name: String, + side: String, + state: String, + id: i32, +} + +fn main() -> anyhow::Result<()> { + rerun_if_changed(["extracted/packets.json"]); + + let packets: Vec = serde_json::from_str(include_str!("extracted/packets.json"))?; + + let mut states: BTreeMap = BTreeMap::new(); + + for packet in packets { + let stripped_name = packet.name.strip_suffix("Packet").unwrap_or(&packet.name); + + let name_ident = ident(stripped_name.to_shouty_snake_case()); + let id = packet.id; + + let doc = format!("Side: {}\n\nState: {}", packet.side, packet.state); + + states.entry(packet.state).or_default().extend(quote! { + #[doc = #doc] + pub const #name_ident: i32 = #id; + }); + } + + let out = states + .into_iter() + .map(|(state, consts)| { + let state = ident(state); + quote! { + pub mod #state { + #consts + } + } + }) + .collect(); + + write_generated_file(out, "packet_id.rs")?; + + Ok(()) +} diff --git a/crates/valence_protocol/extracted/packets.json b/crates/valence_protocol/extracted/packets.json new file mode 100644 index 000000000..41d97765b --- /dev/null +++ b/crates/valence_protocol/extracted/packets.json @@ -0,0 +1,1214 @@ +[ + { + "name": "HandshakeC2SPacket", + "state": "handshaking", + "side": "serverbound", + "id": 0 + }, + { + "name": "TeleportConfirmC2SPacket", + "state": "play", + "side": "serverbound", + "id": 0 + }, + { + "name": "QueryBlockNbtC2SPacket", + "state": "play", + "side": "serverbound", + "id": 1 + }, + { + "name": "UpdateDifficultyC2SPacket", + "state": "play", + "side": "serverbound", + "id": 2 + }, + { + "name": "MessageAcknowledgmentC2SPacket", + "state": "play", + "side": "serverbound", + "id": 3 + }, + { + "name": "CommandExecutionC2SPacket", + "state": "play", + "side": "serverbound", + "id": 4 + }, + { + "name": "ChatMessageC2SPacket", + "state": "play", + "side": "serverbound", + "id": 5 + }, + { + "name": "PlayerSessionC2SPacket", + "state": "play", + "side": "serverbound", + "id": 6 + }, + { + "name": "AcknowledgeChunksC2SPacket", + "state": "play", + "side": "serverbound", + "id": 7 + }, + { + "name": "ClientStatusC2SPacket", + "state": "play", + "side": "serverbound", + "id": 8 + }, + { + "name": "ClientOptionsC2SPacket", + "state": "play", + "side": "serverbound", + "id": 9 + }, + { + "name": "RequestCommandCompletionsC2SPacket", + "state": "play", + "side": "serverbound", + "id": 10 + }, + { + "name": "AcknowledgeReconfigurationC2SPacket", + "state": "play", + "side": "serverbound", + "id": 11 + }, + { + "name": "ButtonClickC2SPacket", + "state": "play", + "side": "serverbound", + "id": 12 + }, + { + "name": "ClickSlotC2SPacket", + "state": "play", + "side": "serverbound", + "id": 13 + }, + { + "name": "CloseHandledScreenC2SPacket", + "state": "play", + "side": "serverbound", + "id": 14 + }, + { + "name": "SlotChangedStateC2SPacket", + "state": "play", + "side": "serverbound", + "id": 15 + }, + { + "name": "CustomPayloadC2SPacket", + "state": "play", + "side": "serverbound", + "id": 16 + }, + { + "name": "BookUpdateC2SPacket", + "state": "play", + "side": "serverbound", + "id": 17 + }, + { + "name": "QueryEntityNbtC2SPacket", + "state": "play", + "side": "serverbound", + "id": 18 + }, + { + "name": "PlayerInteractEntityC2SPacket", + "state": "play", + "side": "serverbound", + "id": 19 + }, + { + "name": "JigsawGeneratingC2SPacket", + "state": "play", + "side": "serverbound", + "id": 20 + }, + { + "name": "KeepAliveC2SPacket", + "state": "play", + "side": "serverbound", + "id": 21 + }, + { + "name": "UpdateDifficultyLockC2SPacket", + "state": "play", + "side": "serverbound", + "id": 22 + }, + { + "name": "PositionAndOnGround", + "state": "play", + "side": "serverbound", + "id": 23 + }, + { + "name": "Full", + "state": "play", + "side": "serverbound", + "id": 24 + }, + { + "name": "LookAndOnGround", + "state": "play", + "side": "serverbound", + "id": 25 + }, + { + "name": "OnGroundOnly", + "state": "play", + "side": "serverbound", + "id": 26 + }, + { + "name": "VehicleMoveC2SPacket", + "state": "play", + "side": "serverbound", + "id": 27 + }, + { + "name": "BoatPaddleStateC2SPacket", + "state": "play", + "side": "serverbound", + "id": 28 + }, + { + "name": "PickFromInventoryC2SPacket", + "state": "play", + "side": "serverbound", + "id": 29 + }, + { + "name": "QueryPingC2SPacket", + "state": "play", + "side": "serverbound", + "id": 30 + }, + { + "name": "CraftRequestC2SPacket", + "state": "play", + "side": "serverbound", + "id": 31 + }, + { + "name": "UpdatePlayerAbilitiesC2SPacket", + "state": "play", + "side": "serverbound", + "id": 32 + }, + { + "name": "PlayerActionC2SPacket", + "state": "play", + "side": "serverbound", + "id": 33 + }, + { + "name": "ClientCommandC2SPacket", + "state": "play", + "side": "serverbound", + "id": 34 + }, + { + "name": "PlayerInputC2SPacket", + "state": "play", + "side": "serverbound", + "id": 35 + }, + { + "name": "CommonPongC2SPacket", + "state": "play", + "side": "serverbound", + "id": 36 + }, + { + "name": "RecipeCategoryOptionsC2SPacket", + "state": "play", + "side": "serverbound", + "id": 37 + }, + { + "name": "RecipeBookDataC2SPacket", + "state": "play", + "side": "serverbound", + "id": 38 + }, + { + "name": "RenameItemC2SPacket", + "state": "play", + "side": "serverbound", + "id": 39 + }, + { + "name": "ResourcePackStatusC2SPacket", + "state": "play", + "side": "serverbound", + "id": 40 + }, + { + "name": "AdvancementTabC2SPacket", + "state": "play", + "side": "serverbound", + "id": 41 + }, + { + "name": "SelectMerchantTradeC2SPacket", + "state": "play", + "side": "serverbound", + "id": 42 + }, + { + "name": "UpdateBeaconC2SPacket", + "state": "play", + "side": "serverbound", + "id": 43 + }, + { + "name": "UpdateSelectedSlotC2SPacket", + "state": "play", + "side": "serverbound", + "id": 44 + }, + { + "name": "UpdateCommandBlockC2SPacket", + "state": "play", + "side": "serverbound", + "id": 45 + }, + { + "name": "UpdateCommandBlockMinecartC2SPacket", + "state": "play", + "side": "serverbound", + "id": 46 + }, + { + "name": "CreativeInventoryActionC2SPacket", + "state": "play", + "side": "serverbound", + "id": 47 + }, + { + "name": "UpdateJigsawC2SPacket", + "state": "play", + "side": "serverbound", + "id": 48 + }, + { + "name": "UpdateStructureBlockC2SPacket", + "state": "play", + "side": "serverbound", + "id": 49 + }, + { + "name": "UpdateSignC2SPacket", + "state": "play", + "side": "serverbound", + "id": 50 + }, + { + "name": "HandSwingC2SPacket", + "state": "play", + "side": "serverbound", + "id": 51 + }, + { + "name": "SpectatorTeleportC2SPacket", + "state": "play", + "side": "serverbound", + "id": 52 + }, + { + "name": "PlayerInteractBlockC2SPacket", + "state": "play", + "side": "serverbound", + "id": 53 + }, + { + "name": "PlayerInteractItemC2SPacket", + "state": "play", + "side": "serverbound", + "id": 54 + }, + { + "name": "BundleSplitterPacket", + "state": "play", + "side": "clientbound", + "id": 0 + }, + { + "name": "EntitySpawnS2CPacket", + "state": "play", + "side": "clientbound", + "id": 1 + }, + { + "name": "ExperienceOrbSpawnS2CPacket", + "state": "play", + "side": "clientbound", + "id": 2 + }, + { + "name": "EntityAnimationS2CPacket", + "state": "play", + "side": "clientbound", + "id": 3 + }, + { + "name": "StatisticsS2CPacket", + "state": "play", + "side": "clientbound", + "id": 4 + }, + { + "name": "PlayerActionResponseS2CPacket", + "state": "play", + "side": "clientbound", + "id": 5 + }, + { + "name": "BlockBreakingProgressS2CPacket", + "state": "play", + "side": "clientbound", + "id": 6 + }, + { + "name": "BlockEntityUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 7 + }, + { + "name": "BlockEventS2CPacket", + "state": "play", + "side": "clientbound", + "id": 8 + }, + { + "name": "BlockUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 9 + }, + { + "name": "BossBarS2CPacket", + "state": "play", + "side": "clientbound", + "id": 10 + }, + { + "name": "DifficultyS2CPacket", + "state": "play", + "side": "clientbound", + "id": 11 + }, + { + "name": "ChunkSentS2CPacket", + "state": "play", + "side": "clientbound", + "id": 12 + }, + { + "name": "StartChunkSendS2CPacket", + "state": "play", + "side": "clientbound", + "id": 13 + }, + { + "name": "ChunkBiomeDataS2CPacket", + "state": "play", + "side": "clientbound", + "id": 14 + }, + { + "name": "ClearTitleS2CPacket", + "state": "play", + "side": "clientbound", + "id": 15 + }, + { + "name": "CommandSuggestionsS2CPacket", + "state": "play", + "side": "clientbound", + "id": 16 + }, + { + "name": "CommandTreeS2CPacket", + "state": "play", + "side": "clientbound", + "id": 17 + }, + { + "name": "CloseScreenS2CPacket", + "state": "play", + "side": "clientbound", + "id": 18 + }, + { + "name": "InventoryS2CPacket", + "state": "play", + "side": "clientbound", + "id": 19 + }, + { + "name": "ScreenHandlerPropertyUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 20 + }, + { + "name": "ScreenHandlerSlotUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 21 + }, + { + "name": "CooldownUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 22 + }, + { + "name": "ChatSuggestionsS2CPacket", + "state": "play", + "side": "clientbound", + "id": 23 + }, + { + "name": "CustomPayloadS2CPacket", + "state": "play", + "side": "clientbound", + "id": 24 + }, + { + "name": "EntityDamageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 25 + }, + { + "name": "RemoveMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 26 + }, + { + "name": "DisconnectS2CPacket", + "state": "play", + "side": "clientbound", + "id": 27 + }, + { + "name": "ProfilelessChatMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 28 + }, + { + "name": "EntityStatusS2CPacket", + "state": "play", + "side": "clientbound", + "id": 29 + }, + { + "name": "ExplosionS2CPacket", + "state": "play", + "side": "clientbound", + "id": 30 + }, + { + "name": "UnloadChunkS2CPacket", + "state": "play", + "side": "clientbound", + "id": 31 + }, + { + "name": "GameStateChangeS2CPacket", + "state": "play", + "side": "clientbound", + "id": 32 + }, + { + "name": "OpenHorseScreenS2CPacket", + "state": "play", + "side": "clientbound", + "id": 33 + }, + { + "name": "DamageTiltS2CPacket", + "state": "play", + "side": "clientbound", + "id": 34 + }, + { + "name": "WorldBorderInitializeS2CPacket", + "state": "play", + "side": "clientbound", + "id": 35 + }, + { + "name": "KeepAliveS2CPacket", + "state": "play", + "side": "clientbound", + "id": 36 + }, + { + "name": "ChunkDataS2CPacket", + "state": "play", + "side": "clientbound", + "id": 37 + }, + { + "name": "WorldEventS2CPacket", + "state": "play", + "side": "clientbound", + "id": 38 + }, + { + "name": "ParticleS2CPacket", + "state": "play", + "side": "clientbound", + "id": 39 + }, + { + "name": "LightUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 40 + }, + { + "name": "GameJoinS2CPacket", + "state": "play", + "side": "clientbound", + "id": 41 + }, + { + "name": "MapUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 42 + }, + { + "name": "SetTradeOffersS2CPacket", + "state": "play", + "side": "clientbound", + "id": 43 + }, + { + "name": "MoveRelative", + "state": "play", + "side": "clientbound", + "id": 44 + }, + { + "name": "RotateAndMoveRelative", + "state": "play", + "side": "clientbound", + "id": 45 + }, + { + "name": "Rotate", + "state": "play", + "side": "clientbound", + "id": 46 + }, + { + "name": "VehicleMoveS2CPacket", + "state": "play", + "side": "clientbound", + "id": 47 + }, + { + "name": "OpenWrittenBookS2CPacket", + "state": "play", + "side": "clientbound", + "id": 48 + }, + { + "name": "OpenScreenS2CPacket", + "state": "play", + "side": "clientbound", + "id": 49 + }, + { + "name": "SignEditorOpenS2CPacket", + "state": "play", + "side": "clientbound", + "id": 50 + }, + { + "name": "CommonPingS2CPacket", + "state": "play", + "side": "clientbound", + "id": 51 + }, + { + "name": "PingResultS2CPacket", + "state": "play", + "side": "clientbound", + "id": 52 + }, + { + "name": "CraftFailedResponseS2CPacket", + "state": "play", + "side": "clientbound", + "id": 53 + }, + { + "name": "PlayerAbilitiesS2CPacket", + "state": "play", + "side": "clientbound", + "id": 54 + }, + { + "name": "ChatMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 55 + }, + { + "name": "EndCombatS2CPacket", + "state": "play", + "side": "clientbound", + "id": 56 + }, + { + "name": "EnterCombatS2CPacket", + "state": "play", + "side": "clientbound", + "id": 57 + }, + { + "name": "DeathMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 58 + }, + { + "name": "PlayerRemoveS2CPacket", + "state": "play", + "side": "clientbound", + "id": 59 + }, + { + "name": "PlayerListS2CPacket", + "state": "play", + "side": "clientbound", + "id": 60 + }, + { + "name": "LookAtS2CPacket", + "state": "play", + "side": "clientbound", + "id": 61 + }, + { + "name": "PlayerPositionLookS2CPacket", + "state": "play", + "side": "clientbound", + "id": 62 + }, + { + "name": "UnlockRecipesS2CPacket", + "state": "play", + "side": "clientbound", + "id": 63 + }, + { + "name": "EntitiesDestroyS2CPacket", + "state": "play", + "side": "clientbound", + "id": 64 + }, + { + "name": "RemoveEntityStatusEffectS2CPacket", + "state": "play", + "side": "clientbound", + "id": 65 + }, + { + "name": "ScoreboardScoreResetS2CPacket", + "state": "play", + "side": "clientbound", + "id": 66 + }, + { + "name": "ResourcePackRemoveS2CPacket", + "state": "play", + "side": "clientbound", + "id": 67 + }, + { + "name": "ResourcePackSendS2CPacket", + "state": "play", + "side": "clientbound", + "id": 68 + }, + { + "name": "PlayerRespawnS2CPacket", + "state": "play", + "side": "clientbound", + "id": 69 + }, + { + "name": "EntitySetHeadYawS2CPacket", + "state": "play", + "side": "clientbound", + "id": 70 + }, + { + "name": "ChunkDeltaUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 71 + }, + { + "name": "SelectAdvancementTabS2CPacket", + "state": "play", + "side": "clientbound", + "id": 72 + }, + { + "name": "ServerMetadataS2CPacket", + "state": "play", + "side": "clientbound", + "id": 73 + }, + { + "name": "OverlayMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 74 + }, + { + "name": "WorldBorderCenterChangedS2CPacket", + "state": "play", + "side": "clientbound", + "id": 75 + }, + { + "name": "WorldBorderInterpolateSizeS2CPacket", + "state": "play", + "side": "clientbound", + "id": 76 + }, + { + "name": "WorldBorderSizeChangedS2CPacket", + "state": "play", + "side": "clientbound", + "id": 77 + }, + { + "name": "WorldBorderWarningTimeChangedS2CPacket", + "state": "play", + "side": "clientbound", + "id": 78 + }, + { + "name": "WorldBorderWarningBlocksChangedS2CPacket", + "state": "play", + "side": "clientbound", + "id": 79 + }, + { + "name": "SetCameraEntityS2CPacket", + "state": "play", + "side": "clientbound", + "id": 80 + }, + { + "name": "UpdateSelectedSlotS2CPacket", + "state": "play", + "side": "clientbound", + "id": 81 + }, + { + "name": "ChunkRenderDistanceCenterS2CPacket", + "state": "play", + "side": "clientbound", + "id": 82 + }, + { + "name": "ChunkLoadDistanceS2CPacket", + "state": "play", + "side": "clientbound", + "id": 83 + }, + { + "name": "PlayerSpawnPositionS2CPacket", + "state": "play", + "side": "clientbound", + "id": 84 + }, + { + "name": "ScoreboardDisplayS2CPacket", + "state": "play", + "side": "clientbound", + "id": 85 + }, + { + "name": "EntityTrackerUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 86 + }, + { + "name": "EntityAttachS2CPacket", + "state": "play", + "side": "clientbound", + "id": 87 + }, + { + "name": "EntityVelocityUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 88 + }, + { + "name": "EntityEquipmentUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 89 + }, + { + "name": "ExperienceBarUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 90 + }, + { + "name": "HealthUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 91 + }, + { + "name": "ScoreboardObjectiveUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 92 + }, + { + "name": "EntityPassengersSetS2CPacket", + "state": "play", + "side": "clientbound", + "id": 93 + }, + { + "name": "TeamS2CPacket", + "state": "play", + "side": "clientbound", + "id": 94 + }, + { + "name": "ScoreboardScoreUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 95 + }, + { + "name": "SimulationDistanceS2CPacket", + "state": "play", + "side": "clientbound", + "id": 96 + }, + { + "name": "SubtitleS2CPacket", + "state": "play", + "side": "clientbound", + "id": 97 + }, + { + "name": "WorldTimeUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 98 + }, + { + "name": "TitleS2CPacket", + "state": "play", + "side": "clientbound", + "id": 99 + }, + { + "name": "TitleFadeS2CPacket", + "state": "play", + "side": "clientbound", + "id": 100 + }, + { + "name": "PlaySoundFromEntityS2CPacket", + "state": "play", + "side": "clientbound", + "id": 101 + }, + { + "name": "PlaySoundS2CPacket", + "state": "play", + "side": "clientbound", + "id": 102 + }, + { + "name": "EnterReconfigurationS2CPacket", + "state": "play", + "side": "clientbound", + "id": 103 + }, + { + "name": "StopSoundS2CPacket", + "state": "play", + "side": "clientbound", + "id": 104 + }, + { + "name": "GameMessageS2CPacket", + "state": "play", + "side": "clientbound", + "id": 105 + }, + { + "name": "PlayerListHeaderS2CPacket", + "state": "play", + "side": "clientbound", + "id": 106 + }, + { + "name": "NbtQueryResponseS2CPacket", + "state": "play", + "side": "clientbound", + "id": 107 + }, + { + "name": "ItemPickupAnimationS2CPacket", + "state": "play", + "side": "clientbound", + "id": 108 + }, + { + "name": "EntityPositionS2CPacket", + "state": "play", + "side": "clientbound", + "id": 109 + }, + { + "name": "UpdateTickRateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 110 + }, + { + "name": "TickStepS2CPacket", + "state": "play", + "side": "clientbound", + "id": 111 + }, + { + "name": "AdvancementUpdateS2CPacket", + "state": "play", + "side": "clientbound", + "id": 112 + }, + { + "name": "EntityAttributesS2CPacket", + "state": "play", + "side": "clientbound", + "id": 113 + }, + { + "name": "EntityStatusEffectS2CPacket", + "state": "play", + "side": "clientbound", + "id": 114 + }, + { + "name": "SynchronizeRecipesS2CPacket", + "state": "play", + "side": "clientbound", + "id": 115 + }, + { + "name": "SynchronizeTagsS2CPacket", + "state": "play", + "side": "clientbound", + "id": 116 + }, + { + "name": "QueryRequestC2SPacket", + "state": "status", + "side": "serverbound", + "id": 0 + }, + { + "name": "QueryPingC2SPacket", + "state": "status", + "side": "serverbound", + "id": 1 + }, + { + "name": "QueryResponseS2CPacket", + "state": "status", + "side": "clientbound", + "id": 0 + }, + { + "name": "PingResultS2CPacket", + "state": "status", + "side": "clientbound", + "id": 1 + }, + { + "name": "LoginHelloC2SPacket", + "state": "login", + "side": "serverbound", + "id": 0 + }, + { + "name": "LoginKeyC2SPacket", + "state": "login", + "side": "serverbound", + "id": 1 + }, + { + "name": "LoginQueryResponseC2SPacket", + "state": "login", + "side": "serverbound", + "id": 2 + }, + { + "name": "EnterConfigurationC2SPacket", + "state": "login", + "side": "serverbound", + "id": 3 + }, + { + "name": "LoginDisconnectS2CPacket", + "state": "login", + "side": "clientbound", + "id": 0 + }, + { + "name": "LoginHelloS2CPacket", + "state": "login", + "side": "clientbound", + "id": 1 + }, + { + "name": "LoginSuccessS2CPacket", + "state": "login", + "side": "clientbound", + "id": 2 + }, + { + "name": "LoginCompressionS2CPacket", + "state": "login", + "side": "clientbound", + "id": 3 + }, + { + "name": "LoginQueryRequestS2CPacket", + "state": "login", + "side": "clientbound", + "id": 4 + }, + { + "name": "ClientOptionsC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 0 + }, + { + "name": "CustomPayloadC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 1 + }, + { + "name": "ReadyC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 2 + }, + { + "name": "KeepAliveC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 3 + }, + { + "name": "CommonPongC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 4 + }, + { + "name": "ResourcePackStatusC2SPacket", + "state": "configuration", + "side": "serverbound", + "id": 5 + }, + { + "name": "CustomPayloadS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 0 + }, + { + "name": "DisconnectS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 1 + }, + { + "name": "ReadyS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 2 + }, + { + "name": "KeepAliveS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 3 + }, + { + "name": "CommonPingS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 4 + }, + { + "name": "DynamicRegistriesS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 5 + }, + { + "name": "ResourcePackRemoveS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 6 + }, + { + "name": "ResourcePackSendS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 7 + }, + { + "name": "FeaturesS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 8 + }, + { + "name": "SynchronizeTagsS2CPacket", + "state": "configuration", + "side": "clientbound", + "id": 9 + } +] \ No newline at end of file diff --git a/crates/valence_protocol/src/lib.rs b/crates/valence_protocol/src/lib.rs new file mode 100644 index 000000000..da708bc12 --- /dev/null +++ b/crates/valence_protocol/src/lib.rs @@ -0,0 +1,197 @@ +use std::io::Write; + +use anyhow::{anyhow, bail, ensure, Context}; +use num_traits::{FromPrimitive, ToPrimitive}; + +use crate::var_int::VarIntReadError; + +pub mod packets; +pub mod var_int; +mod id { + include!(concat!(env!("OUT_DIR"), "/packet_id.rs")); +} + +pub trait Packet { + type Output<'a>; + + fn read_body<'a>(r: &mut impl McRead<'a>) -> anyhow::Result>; + + fn write_body(&self, w: &mut impl McWrite) -> anyhow::Result<()>; +} + +pub trait PacketMeta { + const ID: i32; +} + +pub trait PacketState {} + +pub trait PacketSide {} + +pub struct Handshaking; + +impl PacketState for Handshaking {} + +pub struct Status; + +impl PacketState for Status {} + +pub struct Login; + +impl PacketState for Login {} + +pub struct Configuration; + +impl PacketState for Configuration {} + +pub struct Serverbound; + +impl PacketSide for Serverbound {} +pub struct Clientbound; + +impl PacketSide for Clientbound {} + +pub trait McWrite { + /// Write a slice of bytes directly to the output without any length prefix. + fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()>; + + /// Write a variable length integer. + fn write_var_int(&mut self, int: i32) -> anyhow::Result<()> { + var_int::write_var_int(int, |b| self.write_bytes(&[b])) + } + + fn write_var_long(&mut self, int: i64) -> anyhow::Result<()> { + var_int::write_var_long(int, |b| self.write_bytes(&[b])) + } + + /// Write a `str`. Errors if the string is longer than 32767 in utf-16 + /// chars. + fn write_str(&mut self, str: &str) -> anyhow::Result<()> { + self.write_str_bounded(str, 32767) + } + + fn write_str_bounded(&mut self, str: &str, max_len: u32) -> anyhow::Result<()> { + let char_count = str.encode_utf16().count(); + + ensure!( + char_count <= max_len as usize, + "utf-16 char count of string ({char_count}) exceeds maximum of {max_len}" + ); + + let len: i32 = str + .len() + .try_into() + .context("string length not representable as `i32`")?; + + self.write_var_int(len)?; + self.write_bytes(str.as_bytes()) + } + + fn write_enum(&mut self, t: &T) -> anyhow::Result<()> { + self.write_var_int(t.to_i32().context("enum not representable as `i32`")?) + } + + fn write_i8(&mut self, int: i8) -> anyhow::Result<()> { + self.write_bytes(&[int as u8]) + } + + fn write_i64(&mut self, int: i64) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } +} + +pub trait McRead<'a> { + fn read_bytes(&mut self, count: usize) -> anyhow::Result<&'a [u8]>; + + fn read_bytes_const(&mut self) -> anyhow::Result<&'a [u8; N]> { + Ok(self.read_bytes(N)?.try_into().expect("invalid slice len")) + } + + fn read_str(&mut self) -> anyhow::Result<&'a str> { + self.read_str_bounded(32767) + } + + fn read_str_bounded(&mut self, max_len: u32) -> anyhow::Result<&'a str> { + let len = self.read_var_int()?; + let len: u32 = len.try_into().context("negative string length")?; + + let max_bytes_per_char = 2; + let max_byte_len = max_len * max_bytes_per_char; + + ensure!( + len <= max_byte_len, + "string byte length of {len} exceeds maximum of {max_byte_len}" + ); + + let str = std::str::from_utf8(self.read_bytes(len as usize)?)?; + + let utf16_len = str.encode_utf16().count(); + + ensure!( + utf16_len <= max_len as usize, + "utf-16 string length of {utf16_len} exceeds maximum of {max_len}" + ); + + Ok(str) + } + + fn read_enum(&mut self) -> anyhow::Result { + let discriminant = self.read_var_int()?; + T::from_i32(discriminant).context("failed to decode enum") + } + + fn read_var_int(&mut self) -> anyhow::Result { + match var_int::read_var_int(|| self.read_u8()) { + Ok(int) => Ok(int), + Err(VarIntReadError::ReadError(e)) => Err(e), + Err(e @ VarIntReadError::TooLarge) => bail!(e), + } + } + + fn read_var_long(&mut self) -> anyhow::Result { + match var_int::read_var_long(|| self.read_u8()) { + Ok(int) => Ok(int), + Err(VarIntReadError::ReadError(e)) => Err(e), + Err(e @ VarIntReadError::TooLarge) => Err(anyhow!(e)), + } + } + + fn read_u8(&mut self) -> anyhow::Result { + let &[byte] = self.read_bytes_const::<1>()?; + Ok(byte) + } + + fn read_i8(&mut self) -> anyhow::Result { + Ok(self.read_u8()? as i8) + } + + fn read_u64(&mut self) -> anyhow::Result { + Ok(u64::from_be_bytes(*self.read_bytes_const::<8>()?)) + } + + fn read_i64(&mut self) -> anyhow::Result { + Ok(self.read_u64()? as i64) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] +pub struct McWriter(pub W); + +impl McWrite for McWriter { + fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()> { + self.0.write_all(bytes).map_err(|e| e.into()) + } +} + +impl<'a> McRead<'a> for &'a [u8] { + fn read_bytes(&mut self, count: usize) -> anyhow::Result<&'a [u8]> { + ensure!( + count <= self.len(), + "attempt to read {count} bytes, but slice has length of {}", + self.len() + ); + + let (l, r) = self.split_at(count); + *self = r; + Ok(l) + } +} diff --git a/crates/valence_protocol/src/packets.rs b/crates/valence_protocol/src/packets.rs new file mode 100644 index 000000000..d09fa42d2 --- /dev/null +++ b/crates/valence_protocol/src/packets.rs @@ -0,0 +1,49 @@ +pub mod handshake_c2s; +pub mod ping_result_s2c; +pub mod query_request_c2s; +pub mod query_response_s2c; +pub mod query_ping_c2s; + +pub use handshake_c2s::HandshakeC2s; + +/* +macro_rules! declare_packets { + ( + $( + $state:ty => { + $( + $side:ty => { + $( + ($id:expr, $packet:ty) + )* + } + )* + } + )* + ) => { + $( + $( + $( + impl crate::PacketMeta<$state, $side> for $packet { + const ID: i32 = $id; + } + )* + )* + )* + } +} + +// macro_rules! decl_body { +// ($id:expr) +// } + +use crate::{Clientbound, Configuration, Handshaking, Login, Serverbound, Status, id}; + +declare_packets! { + Handshaking => { + Clientbound => { + (id::handshaking::HANDSHAKE_C2S, HandshakeC2s<'_>) + } + } +} +*/ diff --git a/crates/valence_protocol/src/packets/handshake_c2s.rs b/crates/valence_protocol/src/packets/handshake_c2s.rs new file mode 100644 index 000000000..32b9f0a22 --- /dev/null +++ b/crates/valence_protocol/src/packets/handshake_c2s.rs @@ -0,0 +1,43 @@ +use num_derive::{FromPrimitive, ToPrimitive}; + +use crate::{Handshaking, McRead, McWrite, Packet, PacketMeta, Serverbound}; + +#[derive(Copy, Clone, Debug)] +pub struct HandshakeC2s<'a> { + pub protocol_version: i32, + pub address: &'a str, + pub port: i32, + pub intended_state: ConnectionIntent, +} + +impl Packet for HandshakeC2s<'_> { + type Output<'a> = HandshakeC2s<'a>; + + fn read_body<'a>(r: &mut impl McRead<'a>) -> anyhow::Result> { + Ok(HandshakeC2s { + protocol_version: r.read_var_int()?, + address: r.read_str_bounded(255)?, + port: r.read_var_int()?, + intended_state: r.read_enum::()?, + }) + } + + fn write_body(&self, w: &mut impl McWrite) -> anyhow::Result<()> { + w.write_var_int(self.protocol_version)?; + w.write_str(self.address)?; + w.write_var_int(self.port)?; + w.write_enum(&self.intended_state)?; + Ok(()) + } + +} + +impl PacketMeta for HandshakeC2s<'_> { + const ID: i32 = crate::id::handshaking::HANDSHAKE_C2S; +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, FromPrimitive, ToPrimitive)] +pub enum ConnectionIntent { + Status = 1, + Login = 2, +} diff --git a/crates/valence_protocol/src/packets/ping_result_s2c.rs b/crates/valence_protocol/src/packets/ping_result_s2c.rs new file mode 100644 index 000000000..08139c7e1 --- /dev/null +++ b/crates/valence_protocol/src/packets/ping_result_s2c.rs @@ -0,0 +1,24 @@ +use crate::{Clientbound, McRead, McWrite, Packet, PacketMeta, Status}; + +#[derive(Copy, Clone, Debug)] +pub struct PingResultS2c { + pub start_time: i64, +} + +impl Packet for PingResultS2c { + type Output<'a> = Self; + + fn read_body<'a>(r: &mut impl McRead<'a>) -> anyhow::Result> { + Ok(Self { + start_time: r.read_i64()?, + }) + } + + fn write_body(&self, w: &mut impl McWrite) -> anyhow::Result<()> { + w.write_i64(self.start_time) + } +} + +impl PacketMeta for PingResultS2c { + const ID: i32 = crate::id::status::PING_RESULT_S2C; +} diff --git a/crates/valence_protocol/src/packets/query_ping_c2s.rs b/crates/valence_protocol/src/packets/query_ping_c2s.rs new file mode 100644 index 000000000..6b16e1ea1 --- /dev/null +++ b/crates/valence_protocol/src/packets/query_ping_c2s.rs @@ -0,0 +1,24 @@ +use crate::{McRead, McWrite, Packet, PacketMeta, Serverbound, Status}; + +#[derive(Copy, Clone, Debug)] +pub struct QueryPingC2s { + pub start_time: i64, +} + +impl Packet for QueryPingC2s { + type Output<'a> = Self; + + fn read_body<'a>(r: &mut impl McRead<'a>) -> anyhow::Result> { + Ok(Self { + start_time: r.read_i64()?, + }) + } + + fn write_body(&self, w: &mut impl McWrite) -> anyhow::Result<()> { + w.write_i64(self.start_time) + } +} + +impl PacketMeta for QueryPingC2s { + const ID: i32 = crate::id::status::QUERY_PING_C2S; +} diff --git a/crates/valence_protocol/src/packets/query_request_c2s.rs b/crates/valence_protocol/src/packets/query_request_c2s.rs new file mode 100644 index 000000000..0d96c65f6 --- /dev/null +++ b/crates/valence_protocol/src/packets/query_request_c2s.rs @@ -0,0 +1,20 @@ +use crate::{McRead, McWrite, Packet, PacketMeta, Serverbound, Status}; + +#[derive(Copy, Clone, Debug)] +pub struct QueryRequestC2s; + +impl Packet for QueryRequestC2s { + type Output<'a> = Self; + + fn read_body<'a>(_r: &mut impl McRead<'a>) -> anyhow::Result> { + Ok(Self) + } + + fn write_body(&self, _w: &mut impl McWrite) -> anyhow::Result<()> { + Ok(()) + } +} + +impl PacketMeta for QueryRequestC2s { + const ID: i32 = crate::id::status::QUERY_REQUEST_C2S; +} diff --git a/crates/valence_protocol/src/packets/query_response_s2c.rs b/crates/valence_protocol/src/packets/query_response_s2c.rs new file mode 100644 index 000000000..b7920978d --- /dev/null +++ b/crates/valence_protocol/src/packets/query_response_s2c.rs @@ -0,0 +1,24 @@ +use crate::{Clientbound, Packet, PacketMeta, Status}; + +#[derive(Copy, Clone, Debug)] +pub struct QueryResponseS2c<'a> { + pub json: &'a str +} + +impl Packet for QueryResponseS2c<'_> { + type Output<'a> = QueryResponseS2c<'a>; + + fn read_body<'a>(r: &mut impl crate::McRead<'a>) -> anyhow::Result> { + Ok(QueryResponseS2c { + json: r.read_str()?, + }) + } + + fn write_body(&self, w: &mut impl crate::McWrite) -> anyhow::Result<()> { + w.write_str(self.json) + } +} + +impl PacketMeta for QueryResponseS2c<'_> { + const ID: i32 = crate::id::status::QUERY_RESPONSE_S2C; +} diff --git a/crates/valence_protocol/src/var_int.rs b/crates/valence_protocol/src/var_int.rs new file mode 100644 index 000000000..d0c35b77e --- /dev/null +++ b/crates/valence_protocol/src/var_int.rs @@ -0,0 +1,97 @@ +use thiserror::Error; + +#[inline] +pub fn read_var_int(mut read_byte: F) -> Result> +where + F: FnMut() -> Result, +{ + let mut val = 0; + for i in 0..VAR_INT_MAX_LEN { + let byte = read_byte()?; + + val |= (byte as i32 & 0x7F) << (i * 7); + + if byte & 0x80 == 0 { + return Ok(val); + } + } + + Err(VarIntReadError::TooLarge) +} + +#[inline] +pub fn write_var_int(int: i32, mut write_byte: F) -> Result<(), E> +where + F: FnMut(u8) -> Result<(), E>, +{ + let mut int = int as u32; + + loop { + if int & 0xFFFFFF80 == 0 { + write_byte(int as u8)?; + return Ok(()); + } + + write_byte(int as u8 | 0x80)?; + + int >>= 7; + } +} + +#[inline] +pub fn read_var_long(mut read_byte: F) -> Result> +where + F: FnMut() -> Result, +{ + let mut val = 0; + for i in 0..VAR_LONG_MAX_LEN { + let byte = read_byte()?; + + val |= (byte as i64 & 0x7F) << (i * 7); + + if byte & 0x80 == 0 { + return Ok(val); + } + } + + Err(VarIntReadError::TooLarge) +} + +#[inline] +pub fn write_var_long(int: i64, mut write_byte: F) -> Result<(), E> +where + F: FnMut(u8) -> Result<(), E>, +{ + let mut int = int as u64; + + loop { + if int & 0xFFFFFFFFFFFFFF80 == 0 { + write_byte(int as u8)?; + return Ok(()); + } + + write_byte(int as u8 | 0x80)?; + + int >>= 7; + } +} + +/// Returns the number of bytes the varint will occupy once written. +#[inline] +pub fn var_int_len(int: i32) -> usize { + match int { + 0 => 1, + n => (31 - n.leading_zeros() as usize) / 7 + 1, + } +} + +pub const VAR_INT_MAX_LEN: usize = 5; +pub const VAR_LONG_MAX_LEN: usize = 10; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Error)] +pub enum VarIntReadError { + #[error(transparent)] + ReadError(#[from] E), + #[error("var int is too large")] + TooLarge, +} diff --git a/crates/valence_protocol_macros/src/packet.rs b/crates/valence_protocol_macros/src/packet.rs index 9d2cdd559..171b05f2f 100644 --- a/crates/valence_protocol_macros/src/packet.rs +++ b/crates/valence_protocol_macros/src/packet.rs @@ -2,67 +2,88 @@ use heck::ToShoutySnakeCase; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote; use syn::spanned::Spanned; -use syn::{parse2, parse_quote, Attribute, DeriveInput, Error, Expr, LitInt, LitStr, Result}; +use syn::{parse2, parse_quote, Attribute, DeriveInput, Error, Expr, LitInt, LitStr, Result, Type}; use crate::add_trait_bounds; pub(super) fn derive_packet(item: TokenStream) -> Result { let mut input = parse2::(item)?; - let packet_attr = parse_packet_helper_attr(&input.attrs)?.unwrap_or_default(); + let mut output = TokenStream::new(); - let name = input.ident.clone(); + let mut helper_attrs = vec![]; - let name_str = if let Some(attr_name) = packet_attr.name { - attr_name.value() - } else { - name.to_string() - }; - - let packet_id: Expr = match packet_attr.id { - Some(expr) => expr, - None => match syn::parse_str::(&name_str.to_shouty_snake_case()) { - Ok(ident) => parse_quote!(::valence_protocol::packet_id::#ident), - Err(_) => { - return Err(Error::new( - packet_attr.span, - "missing valid `id = ...` value from `packet` attr", - )) - } - }, - }; + for attr in &input.attrs { + if let Some(helper) = parse_packet_helper_attr(attr)? { + helper_attrs.push(helper); + } + } - add_trait_bounds(&mut input.generics, quote!(::std::fmt::Debug)); + if helper_attrs.is_empty() { + helper_attrs.push(PacketAttr { + span: Span::call_site(), + id: Default::default(), + tag: Default::default(), + name: Default::default(), + side: Default::default(), + state: Default::default(), + }); + } - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + for packet_attr in helper_attrs { + let type_name = input.ident.clone(); + + let name_str = if let Some(attr_name) = packet_attr.name { + attr_name.value() + } else { + type_name.to_string() + }; + + let packet_id: Expr = match packet_attr.id { + Some(expr) => expr, + None => match syn::parse_str::(&name_str.to_shouty_snake_case()) { + Ok(ident) => parse_quote!(::valence_protocol::packet::id::#ident), + Err(_) => { + return Err(Error::new( + packet_attr.span, + "missing valid `id = ...` value from `packet` helper attribute", + )) + } + }, + }; + + add_trait_bounds(&mut input.generics, quote!(::std::fmt::Debug)); + + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let side = if let Some(side_attr) = packet_attr.side { + side_attr + } else if name_str.to_lowercase().ends_with("s2c") { + parse_quote!(::valence_protocol::packet::PacketS2c) + } else if name_str.to_lowercase().ends_with("c2s") { + parse_quote!(::valence_protocol::packet::PacketC2s) + } else { + return Err(Error::new( + packet_attr.span, + "missing `side = ...` value from `packet` helper attribute", + )); + }; + + let state = packet_attr + .state + .unwrap_or_else(|| parse_quote!(::valence_protocol::packet::PacketPlay)); + + output.extend(quote! { + impl #impl_generics ::valence_protocol::packet::Packet<#side, #state> for #type_name #ty_generics + #where_clause + { + const ID: i32 = #packet_id; + const NAME: &'static str = #name_str; + } + }); + } - let side = if let Some(side_attr) = packet_attr.side { - side_attr - } else if name_str.to_lowercase().ends_with("s2c") { - parse_quote!(::valence_protocol::PacketSide::Clientbound) - } else if name_str.to_lowercase().ends_with("c2s") { - parse_quote!(::valence_protocol::PacketSide::Serverbound) - } else { - return Err(Error::new( - packet_attr.span, - "missing `side = PacketSide::...` value from `packet` attribute", - )); - }; - - let state = packet_attr - .state - .unwrap_or_else(|| parse_quote!(::valence_protocol::PacketState::Play)); - - Ok(quote! { - impl #impl_generics ::valence_protocol::__private::Packet for #name #ty_generics - #where_clause - { - const ID: i32 = #packet_id; - const NAME: &'static str = #name_str; - const SIDE: ::valence_protocol::PacketSide = #side; - const STATE: ::valence_protocol::PacketState = #state; - } - }) + Ok(output) } struct PacketAttr { @@ -70,59 +91,44 @@ struct PacketAttr { id: Option, tag: Option, name: Option, - side: Option, - state: Option, + side: Option, + state: Option, } -impl Default for PacketAttr { - fn default() -> Self { - Self { - span: Span::call_site(), - id: Default::default(), - tag: Default::default(), - name: Default::default(), - side: Default::default(), - state: Default::default(), - } - } -} - -fn parse_packet_helper_attr(attrs: &[Attribute]) -> Result> { - for attr in attrs { - if attr.path().is_ident("packet") { - let mut res = PacketAttr { - span: attr.span(), - id: None, - tag: None, - name: None, - side: None, - state: None, - }; - - attr.parse_nested_meta(|meta| { - if meta.path.is_ident("id") { - res.id = Some(meta.value()?.parse::()?); - Ok(()) - } else if meta.path.is_ident("tag") { - res.tag = Some(meta.value()?.parse::()?.base10_parse::()?); - Ok(()) - } else if meta.path.is_ident("name") { - res.name = Some(meta.value()?.parse::()?); - Ok(()) - } else if meta.path.is_ident("side") { - res.side = Some(meta.value()?.parse::()?); - Ok(()) - } else if meta.path.is_ident("state") { - res.state = Some(meta.value()?.parse::()?); - Ok(()) - } else { - Err(meta.error("unrecognized packet argument")) - } - })?; +fn parse_packet_helper_attr(attr: &Attribute) -> Result> { + if attr.path().is_ident("packet") { + let mut res = PacketAttr { + span: attr.span(), + id: None, + tag: None, + name: None, + side: None, + state: None, + }; + + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("id") { + res.id = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("tag") { + res.tag = Some(meta.value()?.parse::()?.base10_parse::()?); + Ok(()) + } else if meta.path.is_ident("name") { + res.name = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("side") { + res.side = Some(meta.value()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("state") { + res.state = Some(meta.value()?.parse::()?); + Ok(()) + } else { + Err(meta.error("unrecognized #[packet(...)] argument")) + } + })?; - return Ok(Some(res)); - } + Ok(Some(res)) + } else { + Ok(None) } - - Ok(None) } diff --git a/extractor/copy_extractor_output.sh b/extractor/copy_extractor_output.sh index 5724b665b..3962c65d2 100755 --- a/extractor/copy_extractor_output.sh +++ b/extractor/copy_extractor_output.sh @@ -7,8 +7,9 @@ set -euxo pipefail cd "$(dirname "$0")" -cp run/valence_extractor_output/{entities,misc}.json ../crates/valence_entity/extracted/ -cp run/valence_extractor_output/{attributes,blocks,effects,items,packets,sounds}.json ../crates/valence_generated/extracted/ -cp run/valence_extractor_output/translation_keys.json ../crates/valence_lang/extracted/ -cp run/valence_extractor_output/{registry_codec.dat,tags.json} ../crates/valence_registry/extracted/ -cp run/valence_extractor_output/packets.json ../tools/packet_inspector/extracted/ +# cp run/valence_extractor_output/{entities,misc}.json ../crates/valence_entity/extracted/ +# cp run/valence_extractor_output/{attributes,blocks,effects,items,packets,sounds}.json ../crates/valence_generated/extracted/ +# cp run/valence_extractor_output/translation_keys.json ../crates/valence_lang/extracted/ +# cp run/valence_extractor_output/{registry_codec.dat,tags.json} ../crates/valence_registry/extracted/ +# cp run/valence_extractor_output/packets.json ../tools/packet_inspector/extracted/ +cp run/valence_extractor_output/packets.json ../crates/valence_protocol/extracted/ diff --git a/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java b/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java index 440ffcb8c..18263c0b5 100644 --- a/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java +++ b/extractor/src/main/java/rs/valence/extractor/extractors/Packets.java @@ -23,16 +23,16 @@ public String fileName() { public void extract(MinecraftServer server, DataOutput output, Gson gson) throws IOException { var packetsJson = new JsonArray(); - for (var side : NetworkSide.values()) { - for (var state : NetworkState.values()) { + for (var state : NetworkState.values()) { + for (var side : NetworkSide.values()) { var map = state.getPacketIdToPacketMap(side); for (var id : new TreeSet<>(map.keySet())) { var packetJson = new JsonObject(); packetJson.addProperty("name", map.get(id.intValue()).getSimpleName()); - packetJson.addProperty("side", side.name().toLowerCase(Locale.ROOT)); packetJson.addProperty("state", state.name().toLowerCase(Locale.ROOT)); + packetJson.addProperty("side", side.name().toLowerCase(Locale.ROOT)); packetJson.addProperty("id", id); packetsJson.add(packetJson); diff --git a/rustfmt.toml b/rustfmt.toml index 7788221a5..f48e486e8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -5,7 +5,7 @@ imports_granularity = "Module" group_imports = "StdExternalCrate" format_code_in_doc_comments = true format_macro_matchers = true -hex_literal_case = "Lower" +hex_literal_case = "Upper" format_strings = true use_field_init_shorthand = true use_try_shorthand = true From 7d8dc774236eb9470eb8e1f8a995d3d78fa3c04d Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Sun, 3 Mar 2024 16:06:38 +0000 Subject: [PATCH 10/11] Expand `McRead` and `McWrite` traits --- crates/valence_protocol/src/lib.rs | 314 ++++++++++++++++++++++--- crates/valence_protocol/src/packets.rs | 40 ---- 2 files changed, 285 insertions(+), 69 deletions(-) diff --git a/crates/valence_protocol/src/lib.rs b/crates/valence_protocol/src/lib.rs index da708bc12..5015f8421 100644 --- a/crates/valence_protocol/src/lib.rs +++ b/crates/valence_protocol/src/lib.rs @@ -1,4 +1,5 @@ -use std::io::Write; +use std::io::{Cursor, Write}; +use std::mem::{self, MaybeUninit}; use anyhow::{anyhow, bail, ensure, Context}; use num_traits::{FromPrimitive, ToPrimitive}; @@ -51,30 +52,31 @@ pub struct Clientbound; impl PacketSide for Clientbound {} pub trait McWrite { - /// Write a slice of bytes directly to the output without any length prefix. + /// Write a slice of bytes directly to the output without a length prefix. fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()>; - /// Write a variable length integer. - fn write_var_int(&mut self, int: i32) -> anyhow::Result<()> { - var_int::write_var_int(int, |b| self.write_bytes(&[b])) - } + fn write_byte_slice(&mut self, bytes: &[u8]) -> anyhow::Result<()> { + let len: i32 = bytes + .len() + .try_into() + .context("byte slice length exceeds `i32::MAX`")?; - fn write_var_long(&mut self, int: i64) -> anyhow::Result<()> { - var_int::write_var_long(int, |b| self.write_bytes(&[b])) + self.write_var_int(len)?; + self.write_bytes(bytes) } - /// Write a `str`. Errors if the string is longer than 32767 in utf-16 - /// chars. + /// Write a `str`. Errors if the string is longer than + /// [`DEFAULT_MAX_STRING_LENGTH`] in UTF-16 chars. fn write_str(&mut self, str: &str) -> anyhow::Result<()> { - self.write_str_bounded(str, 32767) + self.write_str_bounded(str, DEFAULT_MAX_STRING_LENGTH) } - fn write_str_bounded(&mut self, str: &str, max_len: u32) -> anyhow::Result<()> { + fn write_str_bounded(&mut self, str: &str, max_char_count: u32) -> anyhow::Result<()> { let char_count = str.encode_utf16().count(); ensure!( - char_count <= max_len as usize, - "utf-16 char count of string ({char_count}) exceeds maximum of {max_len}" + char_count <= max_char_count as usize, + "utf-16 char count of string ({char_count}) exceeds maximum of {max_char_count}" ); let len: i32 = str @@ -86,19 +88,70 @@ pub trait McWrite { self.write_bytes(str.as_bytes()) } - fn write_enum(&mut self, t: &T) -> anyhow::Result<()> { - self.write_var_int(t.to_i32().context("enum not representable as `i32`")?) + fn write_enum(&mut self, val: &T) -> anyhow::Result<()> { + self.write_var_int(val.to_i32().context("enum not representable as `i32`")?) + } + + /// Write a variable length integer. + fn write_var_int(&mut self, int: i32) -> anyhow::Result<()> { + var_int::write_var_int(int, |b| self.write_bytes(&[b])) + } + + fn write_var_long(&mut self, int: i64) -> anyhow::Result<()> { + var_int::write_var_long(int, |b| self.write_bytes(&[b])) + } + + fn write_u8(&mut self, int: u8) -> anyhow::Result<()> { + self.write_bytes(&[int]) } fn write_i8(&mut self, int: i8) -> anyhow::Result<()> { self.write_bytes(&[int as u8]) } + fn write_u16(&mut self, int: u16) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_i16(&mut self, int: i16) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_u32(&mut self, int: u32) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_i32(&mut self, int: i32) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_u64(&mut self, int: u64) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + fn write_i64(&mut self, int: i64) -> anyhow::Result<()> { self.write_bytes(&int.to_be_bytes()) } + + fn write_u128(&mut self, int: u128) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_i128(&mut self, int: i128) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_f32(&mut self, int: f32) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } + + fn write_f64(&mut self, int: f64) -> anyhow::Result<()> { + self.write_bytes(&int.to_be_bytes()) + } } +/// A source of contiguous bytes for Minecraft packets to read from. The +/// interface is similar to Minecraft's `PacketByteBuf` class. pub trait McRead<'a> { fn read_bytes(&mut self, count: usize) -> anyhow::Result<&'a [u8]>; @@ -106,16 +159,69 @@ pub trait McRead<'a> { Ok(self.read_bytes(N)?.try_into().expect("invalid slice len")) } + /// Read an array of values from the input. The array is not length + /// prefixed. + fn read_array(&mut self, mut f: F) -> anyhow::Result<[T; N]> + where + F: FnMut(&mut Self) -> anyhow::Result, + { + // TODO: use std::array::try_from_fn when stabilized. + + struct Guard { + array: [MaybeUninit; N], + initialized: usize, + } + + impl Drop for Guard { + fn drop(&mut self) { + unsafe { std::ptr::drop_in_place(self.array.as_mut_slice()) }; + } + } + + // This is what `ArrayVec::new` does. + let initial_array: [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; + + let mut guard = Guard { + array: initial_array, + initialized: 0, + }; + + while guard.initialized < N { + *unsafe { guard.array.get_unchecked_mut(guard.initialized) } = + MaybeUninit::new(f(self)?); + + guard.initialized += 1; + } + + let res: [T; N] = unsafe { std::mem::transmute_copy(&guard.array) }; + + std::mem::forget(guard); + + Ok(res) + } + + /// Read a varint-prefixed slice of bytes. There is no length limit. + fn read_byte_slice(&mut self) -> anyhow::Result<&'a [u8]> { + let len: u32 = self + .read_var_int()? + .try_into() + .context("negative byte slice length")?; + + self.read_bytes(len as usize) + } + fn read_str(&mut self) -> anyhow::Result<&'a str> { - self.read_str_bounded(32767) + self.read_str_bounded(DEFAULT_MAX_STRING_LENGTH) } - fn read_str_bounded(&mut self, max_len: u32) -> anyhow::Result<&'a str> { - let len = self.read_var_int()?; - let len: u32 = len.try_into().context("negative string length")?; + fn read_str_bounded(&mut self, max_char_count: u32) -> anyhow::Result<&'a str> { + let len: u32 = self + .read_var_int()? + .try_into() + .context("negative string length")?; - let max_bytes_per_char = 2; - let max_byte_len = max_len * max_bytes_per_char; + let max_bytes_per_char = 4; + let max_byte_len = max_char_count * max_bytes_per_char; ensure!( len <= max_byte_len, @@ -124,11 +230,11 @@ pub trait McRead<'a> { let str = std::str::from_utf8(self.read_bytes(len as usize)?)?; - let utf16_len = str.encode_utf16().count(); + let utf16_char_count = str.encode_utf16().count(); ensure!( - utf16_len <= max_len as usize, - "utf-16 string length of {utf16_len} exceeds maximum of {max_len}" + utf16_char_count <= max_char_count as usize, + "UTF-16 string length of {utf16_char_count} exceeds maximum of {max_char_count}" ); Ok(str) @@ -139,6 +245,38 @@ pub trait McRead<'a> { T::from_i32(discriminant).context("failed to decode enum") } + fn read_option(&mut self, f: F) -> anyhow::Result> + where + F: FnOnce(&mut Self) -> anyhow::Result, + { + self.read_bool()?.then(|| f(self)).transpose() + } + + fn read_collection(&mut self, cf: CF, mut f: F) -> anyhow::Result + where + C: Extend, + CF: FnOnce(usize) -> C, + F: FnMut(&mut Self) -> anyhow::Result, + { + let len = self.read_var_int()?; + let len: usize = len.try_into().context("invalid collection length")?; + + let mut collection = cf(cautious_capacity::(len)); + + for _ in 0..len { + collection.extend([f(self)?]); + } + + Ok(collection) + } + + fn read_vec(&mut self, f: F) -> anyhow::Result> + where + F: FnMut(&mut Self) -> anyhow::Result, + { + self.read_collection(Vec::with_capacity, f) + } + fn read_var_int(&mut self) -> anyhow::Result { match var_int::read_var_int(|| self.read_u8()) { Ok(int) => Ok(int), @@ -155,24 +293,65 @@ pub trait McRead<'a> { } } + fn read_bool(&mut self) -> anyhow::Result { + let byte = self.read_u8()?; + ensure!(byte <= 1, "boolean byte is not zero or one (got {byte})"); + Ok(byte == 1) + } + fn read_u8(&mut self) -> anyhow::Result { - let &[byte] = self.read_bytes_const::<1>()?; + let &[byte] = self.read_bytes_const()?; Ok(byte) } fn read_i8(&mut self) -> anyhow::Result { - Ok(self.read_u8()? as i8) + let &[byte] = self.read_bytes_const()?; + Ok(byte as i8) + } + + fn read_u16(&mut self) -> anyhow::Result { + Ok(u16::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_i16(&mut self) -> anyhow::Result { + Ok(i16::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_u32(&mut self) -> anyhow::Result { + Ok(u32::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_i32(&mut self) -> anyhow::Result { + Ok(i32::from_be_bytes(*self.read_bytes_const()?)) } fn read_u64(&mut self) -> anyhow::Result { - Ok(u64::from_be_bytes(*self.read_bytes_const::<8>()?)) + Ok(u64::from_be_bytes(*self.read_bytes_const()?)) } fn read_i64(&mut self) -> anyhow::Result { - Ok(self.read_u64()? as i64) + Ok(i64::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_u128(&mut self) -> anyhow::Result { + Ok(u128::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_i128(&mut self) -> anyhow::Result { + Ok(i128::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_f32(&mut self) -> anyhow::Result { + Ok(f32::from_be_bytes(*self.read_bytes_const()?)) + } + + fn read_f64(&mut self) -> anyhow::Result { + Ok(f64::from_be_bytes(*self.read_bytes_const()?)) } } +pub const DEFAULT_MAX_STRING_LENGTH: u32 = 32767; + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] pub struct McWriter(pub W); @@ -182,6 +361,29 @@ impl McWrite for McWriter { } } +impl From for McWriter { + fn from(value: W) -> Self { + Self(value) + } +} + +impl<'a> McRead<'a> for Cursor<&'a [u8]> { + fn read_bytes(&mut self, count: usize) -> anyhow::Result<&'a [u8]> { + let remaining_slice = + &self.get_ref()[self.position().min(self.get_ref().len() as u64) as usize..]; + + ensure!( + remaining_slice.len() <= count, + "attempt to read {count} bytes, but cursor has {} bytes remaining", + remaining_slice.len() + ); + + self.set_position(self.position() + count as u64); + + Ok(&remaining_slice[..count]) + } +} + impl<'a> McRead<'a> for &'a [u8] { fn read_bytes(&mut self, count: usize) -> anyhow::Result<&'a [u8]> { ensure!( @@ -195,3 +397,57 @@ impl<'a> McRead<'a> for &'a [u8] { Ok(l) } } + +/// Prevents preallocating too much memory in case we get a malicious or invalid +/// sequence length. +fn cautious_capacity(size_hint: usize) -> usize { + const MAX_PREALLOC_BYTES: usize = 1024 * 1024; + + if mem::size_of::() == 0 { + 0 + } else { + size_hint.min(MAX_PREALLOC_BYTES / mem::size_of::()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn write_read_array() { + let mut buf: McWriter> = McWriter(vec![]); + + buf.write_str("abc").unwrap(); + buf.write_str("123").unwrap(); + + let mut reader = buf.0.as_slice(); + + let res: [String; 2] = reader + .read_array(|r| r.read_str().map(String::from)) + .unwrap(); + + let _: [&str; 0] = reader.read_array(|r| r.read_str()).unwrap(); + + assert_eq!(&res, &["abc", "123"]); + } + + #[test] + #[should_panic = "expect the unexpected"] + fn read_array_panic() { + let mut buf: McWriter> = McWriter(vec![]); + + buf.write_str("abc").unwrap(); + buf.write_str("123").unwrap(); + + let mut reader = buf.0.as_slice(); + + let _: [String; 2] = reader + .read_array(|r| { + let s = r.read_str()?; + assert_eq!(s, "abc", "expect the unexpected"); + Ok(s.into()) + }) + .unwrap(); + } +} diff --git a/crates/valence_protocol/src/packets.rs b/crates/valence_protocol/src/packets.rs index d09fa42d2..df0bb1a57 100644 --- a/crates/valence_protocol/src/packets.rs +++ b/crates/valence_protocol/src/packets.rs @@ -6,44 +6,4 @@ pub mod query_ping_c2s; pub use handshake_c2s::HandshakeC2s; -/* -macro_rules! declare_packets { - ( - $( - $state:ty => { - $( - $side:ty => { - $( - ($id:expr, $packet:ty) - )* - } - )* - } - )* - ) => { - $( - $( - $( - impl crate::PacketMeta<$state, $side> for $packet { - const ID: i32 = $id; - } - )* - )* - )* - } -} -// macro_rules! decl_body { -// ($id:expr) -// } - -use crate::{Clientbound, Configuration, Handshaking, Login, Serverbound, Status, id}; - -declare_packets! { - Handshaking => { - Clientbound => { - (id::handshaking::HANDSHAKE_C2S, HandshakeC2s<'_>) - } - } -} -*/ From 17b1a93a07f82d1b4d1b5011c7e7a893fea766da Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Fri, 8 Mar 2024 14:40:26 +0000 Subject: [PATCH 11/11] Rework `valence_nbt` interface --- crates/valence_nbt/src/binary.rs | 12 +- crates/valence_nbt/src/binary/decode.rs | 314 ++++++++++-------- crates/valence_nbt/src/binary/encode.rs | 168 +++------- .../valence_nbt/src/binary/modified_utf8.rs | 8 +- crates/valence_nbt/src/binary/tests.rs | 19 +- crates/valence_nbt/src/{binary => }/error.rs | 2 +- crates/valence_nbt/src/lib.rs | 11 +- crates/valence_nbt/src/serde.rs | 19 +- crates/valence_nbt/src/serde/ser.rs | 6 +- crates/valence_nbt/src/snbt.rs | 8 +- crates/valence_nbt/src/tag.rs | 1 + 11 files changed, 271 insertions(+), 297 deletions(-) rename crates/valence_nbt/src/{binary => }/error.rs (95%) diff --git a/crates/valence_nbt/src/binary.rs b/crates/valence_nbt/src/binary.rs index d17f95a37..8aa6bd15e 100644 --- a/crates/valence_nbt/src/binary.rs +++ b/crates/valence_nbt/src/binary.rs @@ -18,13 +18,13 @@ //! //! let mut buf = vec![]; //! -//! to_binary(&c, &mut buf, "").unwrap(); +//! to_binary(&mut buf, "", &c).unwrap(); //! ``` //! //! Decode NBT data from its binary form. //! //! ``` -//! use valence_nbt::{compound, from_binary, Compound}; +//! use valence_nbt::{compound, from_binary, Compound, Value}; //! //! let some_bytes = [10, 0, 0, 3, 0, 3, 105, 110, 116, 0, 0, 222, 173, 0]; //! @@ -32,22 +32,20 @@ //! "int" => 0xdead //! }; //! -//! let (nbt, root_name) = from_binary(&mut some_bytes.as_slice()).unwrap(); +//! let (root_name, nbt) = from_binary(&mut some_bytes.as_slice()).unwrap().unwrap(); //! -//! assert_eq!(nbt, expected_value); +//! assert_eq!(nbt, Value::from(expected_value)); //! assert_eq!(root_name, ""); //! ``` mod decode; mod encode; -mod error; mod modified_utf8; #[cfg(test)] mod tests; pub use decode::{from_binary, FromModifiedUtf8, FromModifiedUtf8Error}; -pub use encode::{to_binary, written_size, ToModifiedUtf8}; -pub use error::*; +pub use encode::{to_binary, ToModifiedUtf8}; use crate::Tag; diff --git a/crates/valence_nbt/src/binary/decode.rs b/crates/valence_nbt/src/binary/decode.rs index 607132084..1462fc522 100644 --- a/crates/valence_nbt/src/binary/decode.rs +++ b/crates/valence_nbt/src/binary/decode.rs @@ -1,50 +1,47 @@ use std::borrow::Cow; use std::hash::Hash; -use std::{fmt, mem}; +use std::{fmt, io, mem}; -use byteorder::{BigEndian, ReadBytesExt}; - -use super::{Error, Result}; +use crate::conv::u8_slice_as_i8_slice; use crate::tag::Tag; -use crate::{Compound, List, Value}; +use crate::{Compound, Error, List, Result, Value}; -/// Decodes uncompressed NBT binary data from the provided slice. +/// Decode an NBT value from the given buffer of bytes. /// -/// The string returned in the tuple is the name of the root compound -/// (typically the empty string). -pub fn from_binary<'de, S>(slice: &mut &'de [u8]) -> Result<(Compound, S)> +/// Returns both the root NBT value and the root name (typically the empty +/// string). If the root value is of type [`Tag::End`], then `None` is returned. +/// If the data is malformed or the reader returns an error, then an error is +/// returned. +pub fn from_binary<'a, S>(reader: impl ReadBytes<'a>) -> Result)>> where - S: FromModifiedUtf8<'de> + Hash + Ord, + S: FromModifiedUtf8<'a> + Hash + Ord, { - let mut state = DecodeState { slice, depth: 0 }; + let mut state = DecodeState { reader, depth: 0 }; - let root_tag = state.read_tag()?; + let tag = state.read_tag()?; - if root_tag != Tag::Compound { - return Err(Error::new_owned(format!( - "expected root tag for compound (got {})", - root_tag.name(), - ))); + if tag == Tag::End { + return Ok(None); } - let root_name = state.read_string::()?; - let root = state.read_compound()?; + let name = state.read_string::()?; + let value = state.read_value::(tag)?; debug_assert_eq!(state.depth, 0); - Ok((root, root_name)) + Ok(Some((name, value))) } /// Maximum recursion depth to prevent overflowing the call stack. const MAX_DEPTH: usize = 512; -struct DecodeState<'a, 'de> { - slice: &'a mut &'de [u8], +struct DecodeState { + reader: R, /// Current recursion depth. depth: usize, } -impl<'de> DecodeState<'_, 'de> { +impl<'a, R: ReadBytes<'a>> DecodeState { #[inline] fn check_depth(&mut self, f: impl FnOnce(&mut Self) -> Result) -> Result { if self.depth >= MAX_DEPTH { @@ -58,7 +55,7 @@ impl<'de> DecodeState<'_, 'de> { } fn read_tag(&mut self) -> Result { - match self.slice.read_u8()? { + match self.read_byte()? { 0 => Ok(Tag::End), 1 => Ok(Tag::Byte), 2 => Ok(Tag::Short), @@ -76,53 +73,69 @@ impl<'de> DecodeState<'_, 'de> { } } + /// Read a value identified by the given tag. + /// + /// # Panics + /// + /// Panics if the tag is [`Tag::End`]. + #[track_caller] fn read_value(&mut self, tag: Tag) -> Result> where - S: FromModifiedUtf8<'de> + Hash + Ord, + S: FromModifiedUtf8<'a> + Hash + Ord, { - match tag { - Tag::End => unreachable!("illegal TAG_End argument"), - Tag::Byte => Ok(self.read_byte()?.into()), - Tag::Short => Ok(self.read_short()?.into()), - Tag::Int => Ok(self.read_int()?.into()), - Tag::Long => Ok(self.read_long()?.into()), - Tag::Float => Ok(self.read_float()?.into()), - Tag::Double => Ok(self.read_double()?.into()), - Tag::ByteArray => Ok(self.read_byte_array()?.into()), - Tag::String => Ok(Value::String(self.read_string::()?)), - Tag::List => self.check_depth(|st| Ok(st.read_any_list::()?.into())), - Tag::Compound => self.check_depth(|st| Ok(st.read_compound::()?.into())), - Tag::IntArray => Ok(self.read_int_array()?.into()), - Tag::LongArray => Ok(self.read_long_array()?.into()), - } + Ok(match tag { + Tag::End => panic!("cannot read value of Tag_END"), + Tag::Byte => self.read_byte()?.into(), + Tag::Short => self.read_short()?.into(), + Tag::Int => self.read_int()?.into(), + Tag::Long => self.read_long()?.into(), + Tag::Float => self.read_float()?.into(), + Tag::Double => self.read_double()?.into(), + Tag::ByteArray => self.read_byte_array()?.into(), + Tag::String => Value::String(self.read_string::()?), + Tag::List => self.check_depth(|st| st.read_any_list::())?.into(), + Tag::Compound => self.check_depth(|st| st.read_compound::())?.into(), + Tag::IntArray => self.read_int_array()?.into(), + Tag::LongArray => self.read_long_array()?.into(), + }) } fn read_byte(&mut self) -> Result { - Ok(self.slice.read_i8()?) + Ok(self.reader.read_bytes(1)?[0] as i8) } fn read_short(&mut self) -> Result { - Ok(self.slice.read_i16::()?) + Ok(i16::from_be_bytes( + self.reader.read_bytes(2)?.try_into().unwrap(), + )) } fn read_int(&mut self) -> Result { - Ok(self.slice.read_i32::()?) + Ok(i32::from_be_bytes( + self.reader.read_bytes(4)?.try_into().unwrap(), + )) } fn read_long(&mut self) -> Result { - Ok(self.slice.read_i64::()?) + Ok(i64::from_be_bytes( + self.reader.read_bytes(8)?.try_into().unwrap(), + )) } fn read_float(&mut self) -> Result { - Ok(self.slice.read_f32::()?) + Ok(f32::from_be_bytes( + self.reader.read_bytes(4)?.try_into().unwrap(), + )) } fn read_double(&mut self) -> Result { - Ok(self.slice.read_f64::()?) + Ok(f64::from_be_bytes( + self.reader.read_bytes(8)?.try_into().unwrap(), + )) } fn read_byte_array(&mut self) -> Result> { - let len = self.slice.read_i32::()?; + let len = self.read_int()?; if len.is_negative() { return Err(Error::new_owned(format!( @@ -130,46 +143,38 @@ impl<'de> DecodeState<'_, 'de> { ))); } - if len as usize > self.slice.len() { + if len as usize > self.reader.remaining() { return Err(Error::new_owned(format!( "byte array length of {len} exceeds remainder of input" ))); } - let (left, right) = self.slice.split_at(len as usize); + let slice = u8_slice_as_i8_slice(self.reader.read_bytes(len as usize)?); - let array = left.iter().map(|b| *b as i8).collect(); - *self.slice = right; + debug_assert_eq!(slice.len(), len as usize); - Ok(array) + Ok(slice.into()) } fn read_string(&mut self) -> Result where - S: FromModifiedUtf8<'de>, + S: FromModifiedUtf8<'a>, { - let len = self.slice.read_u16::()?.into(); + let len = self.read_short()? as usize; - if len > self.slice.len() { + if len > self.reader.remaining() { return Err(Error::new_owned(format!( "string of length {len} exceeds remainder of input" ))); } - let (left, right) = self.slice.split_at(len); - - match S::from_modified_utf8(left) { - Ok(str) => { - *self.slice = right; - Ok(str) - } - Err(_) => Err(Error::new_static("could not decode modified UTF-8 data")), - } + S::from_modified_utf8(self.reader.read_bytes(len)?) + .map_err(|_| Error::new_static("could not decode modified UTF-8 data")) } fn read_any_list(&mut self) -> Result> where - S: FromModifiedUtf8<'de> + Hash + Ord, + S: FromModifiedUtf8<'a> + Hash + Ord, { match self.read_tag()? { Tag::End => match self.read_int()? { @@ -178,49 +183,40 @@ impl<'de> DecodeState<'_, 'de> { "TAG_End list with nonzero length of {len}" ))), }, - Tag::Byte => Ok(self.read_list(Tag::Byte, 1, |st| st.read_byte())?.into()), - Tag::Short => Ok(self.read_list(Tag::Short, 2, |st| st.read_short())?.into()), - Tag::Int => Ok(self.read_list(Tag::Int, 4, |st| st.read_int())?.into()), - Tag::Long => Ok(self.read_list(Tag::Long, 8, |st| st.read_long())?.into()), - Tag::Float => Ok(self.read_list(Tag::Float, 4, |st| st.read_float())?.into()), - Tag::Double => Ok(self - .read_list(Tag::Double, 8, |st| st.read_double())? - .into()), + Tag::Byte => Ok(self.read_list(Tag::Byte, |st| st.read_byte())?.into()), + Tag::Short => Ok(self.read_list(Tag::Short, |st| st.read_short())?.into()), + Tag::Int => Ok(self.read_list(Tag::Int, |st| st.read_int())?.into()), + Tag::Long => Ok(self.read_list(Tag::Long, |st| st.read_long())?.into()), + Tag::Float => Ok(self.read_list(Tag::Float, |st| st.read_float())?.into()), + Tag::Double => Ok(self.read_list(Tag::Double, |st| st.read_double())?.into()), Tag::ByteArray => Ok(self - .read_list(Tag::ByteArray, 0, |st| st.read_byte_array())? + .read_list(Tag::ByteArray, |st| st.read_byte_array())? .into()), Tag::String => Ok(List::String( - self.read_list(Tag::String, 0, |st| st.read_string::())?, + self.read_list(Tag::String, |st| st.read_string::())?, )), Tag::List => self.check_depth(|st| { Ok(st - .read_list(Tag::List, 0, |st| st.read_any_list::())? + .read_list(Tag::List, |st| st.read_any_list::())? .into()) }), Tag::Compound => self.check_depth(|st| { Ok(st - .read_list(Tag::Compound, 0, |st| st.read_compound::())? + .read_list(Tag::Compound, |st| st.read_compound::())? .into()) }), Tag::IntArray => Ok(self - .read_list(Tag::IntArray, 0, |st| st.read_int_array())? + .read_list(Tag::IntArray, |st| st.read_int_array())? .into()), Tag::LongArray => Ok(self - .read_list(Tag::LongArray, 0, |st| st.read_long_array())? + .read_list(Tag::LongArray, |st| st.read_long_array())? .into()), } } /// Assumes the element tag has already been read. - /// - /// `min_elem_size` is the minimum size of the list element when encoded. #[inline] - fn read_list( - &mut self, - elem_type: Tag, - elem_size: usize, - mut read_elem: F, - ) -> Result> + fn read_list(&mut self, elem_type: Tag, mut read_elem: F) -> Result> where F: FnMut(&mut Self) -> Result, { @@ -233,16 +229,7 @@ impl<'de> DecodeState<'_, 'de> { ))); } - // Ensure we don't reserve more than the maximum amount of memory required given - // the size of the remaining input. - if len as u64 * elem_size as u64 > self.slice.len() as u64 { - return Err(Error::new_owned(format!( - "{} list of length {len} exceeds remainder of input", - elem_type.name() - ))); - } - - let mut list = Vec::with_capacity(if elem_size == 0 { 0 } else { len as usize }); + let mut list = Vec::with_capacity(cautious_capacity::(len as usize)); for _ in 0..len { list.push(read_elem(self)?); @@ -253,7 +240,7 @@ impl<'de> DecodeState<'_, 'de> { fn read_compound(&mut self) -> Result> where - S: FromModifiedUtf8<'de> + Hash + Ord, + S: FromModifiedUtf8<'a> + Hash + Ord, { let mut compound = Compound::new(); @@ -276,13 +263,15 @@ impl<'de> DecodeState<'_, 'de> { ))); } - if len as u64 * mem::size_of::() as u64 > self.slice.len() as u64 { + if len as u64 * 4 > self.reader.remaining() as u64 { return Err(Error::new_owned(format!( "int array of length {len} exceeds remainder of input" ))); } let mut array = Vec::with_capacity(len as usize); + + // TODO: SIMDify the endian swapping? for _ in 0..len { array.push(self.read_int()?); } @@ -299,13 +288,15 @@ impl<'de> DecodeState<'_, 'de> { ))); } - if len as u64 * mem::size_of::() as u64 > self.slice.len() as u64 { + if len as u64 * 8 > self.reader.remaining() as u64 { return Err(Error::new_owned(format!( "long array of length {len} exceeds remainder of input" ))); } let mut array = Vec::with_capacity(len as usize); + + // TODO: SIMDify the endian swapping? for _ in 0..len { array.push(self.read_long()?); } @@ -314,60 +305,123 @@ impl<'de> DecodeState<'_, 'de> { } } -#[derive(Copy, Clone, Debug)] -pub struct FromModifiedUtf8Error; +/// Prevents preallocating too much memory in case we get a malicious or invalid +/// sequence length. +fn cautious_capacity(size_hint: usize) -> usize { + // TODO: How large can we make this? + const MAX_PREALLOC_BYTES: usize = 2048; -impl fmt::Display for FromModifiedUtf8Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("could not decode modified UTF-8 data") + if mem::size_of::() == 0 { + 0 + } else { + size_hint.min(MAX_PREALLOC_BYTES / mem::size_of::()) } } -impl std::error::Error for FromModifiedUtf8Error {} +pub trait ReadBytes<'a> { + fn read_bytes(&mut self, count: usize) -> io::Result<&'a [u8]>; + + /// Returns the number of remaining bytes in the input. + fn remaining(&self) -> usize; +} + +impl<'a, T> ReadBytes<'a> for &mut T +where + T: ReadBytes<'a>, +{ + fn read_bytes(&mut self, count: usize) -> io::Result<&'a [u8]> { + (**self).read_bytes(count) + } + + fn remaining(&self) -> usize { + (**self).remaining() + } +} + +impl<'a> ReadBytes<'a> for &'a [u8] { + fn read_bytes(&mut self, count: usize) -> io::Result<&'a [u8]> { + if count > self.len() { + return Err(io::ErrorKind::UnexpectedEof.into()); + } + + let (l, r) = self.split_at(count); + *self = r; + Ok(l) + } + + fn remaining(&self) -> usize { + self.len() + } +} + +impl<'a> ReadBytes<'a> for io::Cursor<&'a [u8]> { + fn read_bytes(&mut self, count: usize) -> io::Result<&'a [u8]> { + let remaining_slice = + &self.get_ref()[self.position().min(self.get_ref().len() as u64) as usize..]; + + if count > remaining_slice.len() { + return Err(io::ErrorKind::UnexpectedEof.into()); + } + + self.set_position(self.position() + count as u64); + + Ok(&remaining_slice[..count]) + } + + fn remaining(&self) -> usize { + self.get_ref().len() - self.position() as usize + } +} -/// A string type which can be decoded from Java's [modified UTF-8](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8). pub trait FromModifiedUtf8<'de>: Sized { - fn from_modified_utf8( - modified_utf8: &'de [u8], - ) -> std::result::Result; + fn from_modified_utf8(bytes: &'de [u8]) -> Result; } -impl<'de> FromModifiedUtf8<'de> for Cow<'de, str> { - fn from_modified_utf8( - modified_utf8: &'de [u8], - ) -> std::result::Result { - cesu8::from_java_cesu8(modified_utf8).map_err(move |_| FromModifiedUtf8Error) +impl<'a> FromModifiedUtf8<'a> for Cow<'a, str> { + fn from_modified_utf8(bytes: &'a [u8]) -> Result { + cesu8::from_java_cesu8(bytes).map_err(move |_| FromModifiedUtf8Error) } } -impl<'de> FromModifiedUtf8<'de> for String { - fn from_modified_utf8( - modified_utf8: &'de [u8], - ) -> std::result::Result { - match cesu8::from_java_cesu8(modified_utf8) { +impl<'a> FromModifiedUtf8<'a> for String { + fn from_modified_utf8(bytes: &'a [u8]) -> Result { + match cesu8::from_java_cesu8(bytes) { Ok(str) => Ok(str.into_owned()), Err(_) => Err(FromModifiedUtf8Error), } } } +impl<'a> FromModifiedUtf8<'a> for Box { + fn from_modified_utf8(bytes: &'a [u8]) -> Result { + String::from_modified_utf8(bytes).map(|s| s.into()) + } +} + #[cfg(feature = "java_string")] -impl<'de> FromModifiedUtf8<'de> for Cow<'de, java_string::JavaStr> { - fn from_modified_utf8( - modified_utf8: &'de [u8], - ) -> std::result::Result { - java_string::JavaStr::from_modified_utf8(modified_utf8).map_err(|_| FromModifiedUtf8Error) +impl<'a> FromModifiedUtf8<'a> for Cow<'a, java_string::JavaStr> { + fn from_modified_utf8(bytes: &'a [u8]) -> Result { + java_string::JavaStr::from_modified_utf8(bytes).map_err(|_| FromModifiedUtf8Error) } } #[cfg(feature = "java_string")] -impl<'de> FromModifiedUtf8<'de> for java_string::JavaString { - fn from_modified_utf8( - modified_utf8: &'de [u8], - ) -> std::result::Result { - match java_string::JavaStr::from_modified_utf8(modified_utf8) { +impl<'a> FromModifiedUtf8<'a> for java_string::JavaString { + fn from_modified_utf8(bytes: &'a [u8]) -> Result { + match java_string::JavaStr::from_modified_utf8(bytes) { Ok(str) => Ok(str.into_owned()), Err(_) => Err(FromModifiedUtf8Error), } } } + +#[derive(Copy, Clone, Debug)] +pub struct FromModifiedUtf8Error; + +impl fmt::Display for FromModifiedUtf8Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("could not decode modified UTF-8 string") + } +} + +impl std::error::Error for FromModifiedUtf8Error {} diff --git a/crates/valence_nbt/src/binary/encode.rs b/crates/valence_nbt/src/binary/encode.rs index 037326fbd..0caa15272 100644 --- a/crates/valence_nbt/src/binary/encode.rs +++ b/crates/valence_nbt/src/binary/encode.rs @@ -1,106 +1,31 @@ use std::borrow::Cow; use std::hash::Hash; -use std::io::Write; +use std::io::{self, Write}; use byteorder::{BigEndian, WriteBytesExt}; -use super::{modified_utf8, Error, Result}; +use super::modified_utf8; use crate::conv::i8_slice_as_u8_slice; use crate::tag::Tag; -use crate::{Compound, List, Value}; - -/// Encodes uncompressed NBT binary data to the provided writer. -/// -/// Only compounds are permitted at the top level. This is why the function -/// accepts a [`Compound`] reference rather than a [`Value`]. -/// -/// Additionally, the root compound can be given a name. Typically the empty -/// string `""` is used. -pub fn to_binary(comp: &Compound, writer: W, root_name: &R) -> Result<()> +use crate::value::ValueRef; +use crate::{Compound, Error, List, Result}; + +/// Encode binary NBT data to the given writer. +pub fn to_binary<'a, S>( + writer: impl Write, + root_name: &(impl ToModifiedUtf8 + ?Sized), + value: impl Into>, +) -> Result<()> where - W: Write, - S: ToModifiedUtf8 + Hash + Ord, - R: ToModifiedUtf8 + ?Sized, + S: ToModifiedUtf8 + Hash + Ord + 'a, { + let value = value.into(); + let mut state = EncodeState { writer }; - state.write_tag(Tag::Compound)?; + state.write_tag(value.tag())?; state.write_string(root_name)?; - state.write_compound(comp)?; - - Ok(()) -} - -/// Returns the number of bytes that will be written when -/// [`to_binary`] is called with this compound and root name. -/// -/// If `to_binary` results in `Ok`, the exact number of bytes -/// reported by this function will have been written. If the result is -/// `Err`, then the reported count will be greater than or equal to the -/// number of bytes that have actually been written. -pub fn written_size(comp: &Compound, root_name: &R) -> usize -where - S: ToModifiedUtf8 + Hash + Ord, - R: ToModifiedUtf8 + ?Sized, -{ - fn value_size(val: &Value) -> usize - where - S: ToModifiedUtf8 + Hash + Ord, - { - match val { - Value::Byte(_) => 1, - Value::Short(_) => 2, - Value::Int(_) => 4, - Value::Long(_) => 8, - Value::Float(_) => 4, - Value::Double(_) => 8, - Value::ByteArray(v) => 4 + v.len(), - Value::String(v) => string_size(v), - Value::List(v) => list_size(v), - Value::Compound(v) => compound_size(v), - Value::IntArray(v) => 4 + v.len() * 4, - Value::LongArray(v) => 4 + v.len() * 8, - } - } - - fn list_size(l: &List) -> usize - where - S: ToModifiedUtf8 + Hash + Ord, - { - let elems_size = match l { - List::End => 0, - List::Byte(v) => v.len(), - List::Short(v) => v.len() * 2, - List::Int(v) => v.len() * 4, - List::Long(v) => v.len() * 8, - List::Float(v) => v.len() * 4, - List::Double(v) => v.len() * 8, - List::ByteArray(v) => v.iter().map(|b| 4 + b.len()).sum(), - List::String(v) => v.iter().map(|s| string_size(s)).sum(), - List::List(v) => v.iter().map(list_size).sum(), - List::Compound(v) => v.iter().map(compound_size).sum(), - List::IntArray(v) => v.iter().map(|i| 4 + i.len() * 4).sum(), - List::LongArray(v) => v.iter().map(|l| 4 + l.len() * 8).sum(), - }; - - 1 + 4 + elems_size - } - - fn string_size(s: &S) -> usize { - 2 + s.modified_uf8_len() - } - - fn compound_size(c: &Compound) -> usize - where - S: ToModifiedUtf8 + Hash + Ord, - { - c.iter() - .map(|(k, v)| 1 + string_size(k) + value_size(v)) - .sum::() - + 1 - } - - 1 + string_size(root_name) + compound_size(comp) + state.write_value(value) } struct EncodeState { @@ -112,23 +37,23 @@ impl EncodeState { Ok(self.writer.write_u8(tag as u8)?) } - fn write_value(&mut self, v: &Value) -> Result<()> + fn write_value(&mut self, v: ValueRef) -> Result<()> where S: ToModifiedUtf8 + Hash + Ord, { match v { - Value::Byte(v) => self.write_byte(*v), - Value::Short(v) => self.write_short(*v), - Value::Int(v) => self.write_int(*v), - Value::Long(v) => self.write_long(*v), - Value::Float(v) => self.write_float(*v), - Value::Double(v) => self.write_double(*v), - Value::ByteArray(v) => self.write_byte_array(v), - Value::String(v) => self.write_string(v), - Value::List(v) => self.write_any_list(v), - Value::Compound(v) => self.write_compound(v), - Value::IntArray(v) => self.write_int_array(v), - Value::LongArray(v) => self.write_long_array(v), + ValueRef::Byte(v) => self.write_byte(*v), + ValueRef::Short(v) => self.write_short(*v), + ValueRef::Int(v) => self.write_int(*v), + ValueRef::Long(v) => self.write_long(*v), + ValueRef::Float(v) => self.write_float(*v), + ValueRef::Double(v) => self.write_double(*v), + ValueRef::ByteArray(v) => self.write_byte_array(v), + ValueRef::String(v) => self.write_string(v), + ValueRef::List(v) => self.write_any_list(v), + ValueRef::Compound(v) => self.write_compound(v), + ValueRef::IntArray(v) => self.write_int_array(v), + ValueRef::LongArray(v) => self.write_long_array(v), } } @@ -170,7 +95,10 @@ impl EncodeState { Ok(self.writer.write_all(i8_slice_as_u8_slice(bytes))?) } - fn write_string(&mut self, s: &S) -> Result<()> { + fn write_string(&mut self, s: &S) -> Result<()> + where + S: ToModifiedUtf8 + ?Sized, + { let len = s.modified_uf8_len(); match len.try_into() { @@ -262,7 +190,7 @@ impl EncodeState { for (k, v) in c { self.write_tag(v.tag())?; self.write_string(k)?; - self.write_value(v)?; + self.write_value(v.into())?; } self.write_tag(Tag::End)?; @@ -309,7 +237,7 @@ impl EncodeState { /// A string type which can be encoded into Java's [modified UTF-8](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8). pub trait ToModifiedUtf8 { fn modified_uf8_len(&self) -> usize; - fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> std::io::Result<()>; + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()>; } impl ToModifiedUtf8 for str { @@ -317,7 +245,7 @@ impl ToModifiedUtf8 for str { modified_utf8::encoded_len(self.as_bytes()) } - fn to_modified_utf8(&self, encoded_len: usize, mut writer: W) -> std::io::Result<()> { + fn to_modified_utf8(&self, encoded_len: usize, mut writer: W) -> io::Result<()> { // Conversion to modified UTF-8 always increases the size of the string. // If the new len is equal to the original len, we know it doesn't need // to be re-encoded. @@ -335,7 +263,7 @@ impl ToModifiedUtf8 for Cow<'_, str> { str::modified_uf8_len(self) } - fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> std::io::Result<()> { + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()> { str::to_modified_utf8(self, encoded_len, writer) } } @@ -346,7 +274,17 @@ impl ToModifiedUtf8 for String { str::modified_uf8_len(self) } - fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> std::io::Result<()> { + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()> { + str::to_modified_utf8(self, encoded_len, writer) + } +} + +impl ToModifiedUtf8 for Box { + fn modified_uf8_len(&self) -> usize { + str::modified_uf8_len(self) + } + + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()> { str::to_modified_utf8(self, encoded_len, writer) } } @@ -357,11 +295,7 @@ impl ToModifiedUtf8 for java_string::JavaStr { modified_utf8::encoded_len(self.as_bytes()) } - fn to_modified_utf8( - &self, - _encoded_len: usize, - mut writer: W, - ) -> std::io::Result<()> { + fn to_modified_utf8(&self, _encoded_len: usize, mut writer: W) -> io::Result<()> { writer.write_all(&self.to_modified_utf8()) } } @@ -373,7 +307,7 @@ impl ToModifiedUtf8 for Cow<'_, java_string::JavaStr> { java_string::JavaStr::modified_uf8_len(self) } - fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> std::io::Result<()> { + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()> { ::to_modified_utf8(self, encoded_len, writer) } } @@ -385,7 +319,7 @@ impl ToModifiedUtf8 for java_string::JavaString { java_string::JavaStr::modified_uf8_len(self) } - fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> std::io::Result<()> { + fn to_modified_utf8(&self, encoded_len: usize, writer: W) -> io::Result<()> { ::to_modified_utf8(self, encoded_len, writer) } } diff --git a/crates/valence_nbt/src/binary/modified_utf8.rs b/crates/valence_nbt/src/binary/modified_utf8.rs index 8b6836366..9ee56f77b 100644 --- a/crates/valence_nbt/src/binary/modified_utf8.rs +++ b/crates/valence_nbt/src/binary/modified_utf8.rs @@ -17,7 +17,7 @@ pub(crate) fn write_modified_utf8(mut writer: impl Write, text: &str) -> io::Res while i < bytes.len() { match bytes[i] { 0 => { - writer.write_u16::(0xc080)?; + writer.write_u16::(0xC080)?; i += 1; } b @ 1..=127 => { @@ -35,8 +35,8 @@ pub(crate) fn write_modified_utf8(mut writer: impl Write, text: &str) -> io::Res let s = unsafe { from_utf8_unchecked(&bytes[i..i + w]) }; let c = s.chars().next().unwrap() as u32 - 0x10000; - let s0 = ((c >> 10) as u16) | 0xd800; - let s1 = ((c & 0x3ff) as u16) | 0xdc00; + let s0 = ((c >> 10) as u16) | 0xD800; + let s1 = ((c & 0x3FF) as u16) | 0xDC00; writer.write_all(encode_surrogate(s0).as_slice())?; writer.write_all(encode_surrogate(s1).as_slice())?; @@ -66,7 +66,7 @@ const fn utf8_char_width(first_byte: u8) -> usize { } fn encode_surrogate(surrogate: u16) -> [u8; 3] { - debug_assert!((0xd800..=0xdfff).contains(&surrogate)); + debug_assert!((0xD800..=0xDFFF).contains(&surrogate)); const TAG_CONT_U8: u8 = 0b1000_0000_u8; [ diff --git a/crates/valence_nbt/src/binary/tests.rs b/crates/valence_nbt/src/binary/tests.rs index 837487ef2..635b182f8 100644 --- a/crates/valence_nbt/src/binary/tests.rs +++ b/crates/valence_nbt/src/binary/tests.rs @@ -1,4 +1,3 @@ -use crate::binary::written_size; use crate::tag::Tag; use crate::{compound, from_binary, to_binary, Compound, List, Value}; @@ -10,14 +9,14 @@ fn round_trip() { let compound = example_compound(); - to_binary(&compound, &mut buf, ROOT_NAME).unwrap(); + to_binary(&mut buf, ROOT_NAME, &compound).unwrap(); println!("{buf:?}"); - let (decoded, root_name) = crate::from_binary(&mut buf.as_slice()).unwrap(); + let (root_name, decoded) = from_binary(&mut buf.as_slice()).unwrap().unwrap(); assert_eq!(root_name, ROOT_NAME); - assert_eq!(compound, decoded); + assert_eq!(Value::from(compound), decoded); } #[test] @@ -29,7 +28,7 @@ fn check_min_sizes() { let dbg = format!("{min_val:?}"); let mut buf = vec![]; - to_binary(&compound!("" => min_val), &mut buf, "").unwrap(); + to_binary(&mut buf, "", &compound!("" => min_val)).unwrap(); assert_eq!( expected_size, @@ -88,16 +87,6 @@ fn deeply_nested_list_decode() { let _ = from_binary::(&mut buf.as_slice()); } -#[test] -fn correct_length() { - let c = example_compound(); - - let mut buf = vec![]; - to_binary(&c, &mut buf, "abc").unwrap(); - - assert_eq!(written_size(&c, "abc"), buf.len()); -} - fn example_compound() -> Compound { fn inner() -> Compound { compound! { diff --git a/crates/valence_nbt/src/binary/error.rs b/crates/valence_nbt/src/error.rs similarity index 95% rename from crates/valence_nbt/src/binary/error.rs rename to crates/valence_nbt/src/error.rs index 8c5c4efaf..665a6a27c 100644 --- a/crates/valence_nbt/src/binary/error.rs +++ b/crates/valence_nbt/src/error.rs @@ -2,7 +2,7 @@ use std::error::Error as StdError; use std::fmt::{Display, Formatter}; use std::io; -pub type Result = std::result::Result; +pub type Result = std::result::Result; /// Errors that can occur when encoding or decoding binary NBT. #[derive(Debug)] diff --git a/crates/valence_nbt/src/lib.rs b/crates/valence_nbt/src/lib.rs index 683cd0ed9..957cfd141 100644 --- a/crates/valence_nbt/src/lib.rs +++ b/crates/valence_nbt/src/lib.rs @@ -1,20 +1,28 @@ #![doc = include_str!("../README.md")] +// Run locally with `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --open` +#![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "binary")] +#[cfg_attr(docsrs, doc(cfg(feature = "binary")))] pub use binary::{from_binary, to_binary}; pub use compound::Compound; +pub use error::*; pub use list::List; -pub use tag::Tag; +pub use tag::*; pub use value::Value; #[cfg(feature = "binary")] +#[cfg_attr(docsrs, doc(cfg(feature = "binary")))] pub mod binary; pub mod compound; pub mod conv; +mod error; pub mod list; #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] pub mod serde; #[cfg(feature = "snbt")] +#[cfg_attr(docsrs, doc(cfg(feature = "snbt")))] pub mod snbt; mod tag; pub mod value; @@ -85,6 +93,7 @@ macro_rules! compound { /// /// [`JavaString`]: java_string::JavaString #[cfg(feature = "java_string")] +#[cfg_attr(docsrs, doc(cfg(feature = "java_string")))] #[macro_export] macro_rules! jcompound { ($($key:expr => $value:expr),* $(,)?) => { diff --git a/crates/valence_nbt/src/serde.rs b/crates/valence_nbt/src/serde.rs index 8159f5d7d..793cb26c6 100644 --- a/crates/valence_nbt/src/serde.rs +++ b/crates/valence_nbt/src/serde.rs @@ -1,31 +1,20 @@ use std::fmt; pub use ser::*; -use thiserror::Error; + +use crate::Error; mod de; mod ser; #[cfg(test)] mod tests; -/// Errors that can occur while serializing or deserializing. -#[derive(Clone, Error, Debug)] -#[error("{0}")] - -pub struct Error(Box); - -impl Error { - fn new(s: impl Into>) -> Self { - Self(s.into()) - } -} - impl serde::de::Error for Error { fn custom(msg: T) -> Self where T: fmt::Display, { - Self::new(format!("{msg}")) + Self::new_owned(format!("{msg}")) } } @@ -34,6 +23,6 @@ impl serde::ser::Error for Error { where T: fmt::Display, { - Self::new(format!("{msg}")) + Self::new_owned(format!("{msg}")) } } diff --git a/crates/valence_nbt/src/serde/ser.rs b/crates/valence_nbt/src/serde/ser.rs index 516e9b5a4..99f51902c 100644 --- a/crates/valence_nbt/src/serde/ser.rs +++ b/crates/valence_nbt/src/serde/ser.rs @@ -61,7 +61,7 @@ where macro_rules! unsupported { ($lit:literal) => { - Err(Error::new(concat!("unsupported type: ", $lit))) + Err(Error::new_static(concat!("unsupported type: ", $lit))) }; } @@ -458,7 +458,7 @@ impl SerializeSeq for ValueSerializeSeq { $vec.push(val); Ok(()) } - _ => Err(Error::new(concat!( + _ => Err(Error::new_static(concat!( "heterogeneous NBT list (expected `", stringify!($variant), "` element)" @@ -567,7 +567,7 @@ where self.key = Some(s); Ok(()) } - _ => Err(Error::new("invalid map key type (expected string)")), + _ => Err(Error::new_static("invalid map key type (expected string)")), } } diff --git a/crates/valence_nbt/src/snbt.rs b/crates/valence_nbt/src/snbt.rs index fbe0d634d..e3b796d6c 100644 --- a/crates/valence_nbt/src/snbt.rs +++ b/crates/valence_nbt/src/snbt.rs @@ -45,15 +45,15 @@ impl Display for SnbtErrorKind { #[derive(Debug, Clone, PartialEq, Eq, Copy)] pub struct SnbtError { - pub error_type: SnbtErrorKind, + pub kind: SnbtErrorKind, pub line: usize, pub column: usize, } impl SnbtError { - pub fn new(error_type: SnbtErrorKind, line: usize, column: usize) -> Self { + pub fn new(kind: SnbtErrorKind, line: usize, column: usize) -> Self { Self { - error_type, + kind, line, column, } @@ -62,7 +62,7 @@ impl SnbtError { impl Display for SnbtError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "@ {},{}: {}", self.line, self.column, self.error_type) + write!(f, "@ {},{}: {}", self.line, self.column, self.kind) } } diff --git a/crates/valence_nbt/src/tag.rs b/crates/valence_nbt/src/tag.rs index 4bc9e2639..ecb30f322 100644 --- a/crates/valence_nbt/src/tag.rs +++ b/crates/valence_nbt/src/tag.rs @@ -1,5 +1,6 @@ /// One of the possible NBT data types. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[repr(u8)] pub enum Tag { // Variant order is significant! End,