From 3103e97e18f65805e26b6e725731de34b0525414 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Fri, 24 Jul 2026 12:31:57 +0200 Subject: [PATCH] ci: remove macos-15-intel --- .github/workflows/docker.yml | 2 +- .github/workflows/rust.yml | 4 +- Cargo.lock | 772 ++++++++---------- Cargo.toml | 19 +- pumpkin-codecs/Cargo.toml | 1 - pumpkin-codecs/src/codec/either.rs | 33 +- pumpkin-codecs/src/codec/mod.rs | 2 +- pumpkin-codecs/src/lib.rs | 1 + pumpkin-codegen/Cargo.lock | 104 ++- pumpkin-codegen/Cargo.toml | 4 +- pumpkin-codegen/src/item.rs | 11 +- pumpkin-codegen/src/loot.rs | 20 +- pumpkin-codegen/src/wit/java_packet.rs | 6 +- pumpkin-codegen/src/wit/packet_mapping.rs | 6 +- pumpkin-nbt/benches/nbt.rs | 4 +- pumpkin-nbt/src/compound.rs | 4 +- pumpkin-nbt/src/deserializer.rs | 457 ++++++++--- pumpkin-nbt/src/lib.rs | 36 +- pumpkin-nbt/src/tag.rs | 11 +- .../src/bedrock/server/command_request.rs | 61 +- pumpkin-protocol/src/bedrock/server/emote.rs | 57 +- .../src/bedrock/server/modal_form_response.rs | 22 +- pumpkin-protocol/src/bedrock/server/text.rs | 197 +++-- .../src/codec/item_stack_seralizer.rs | 31 +- .../src/java/client/play/login.rs | 12 +- .../src/java/client/play/player_position.rs | 4 +- pumpkin-protocol/src/java/packet_decoder.rs | 41 +- pumpkin-protocol/src/java/packet_encoder.rs | 82 +- .../config/acknowledge_finish_config.rs | 8 +- .../java/server/config/client_information.rs | 13 +- .../src/java/server/config/cookie_response.rs | 22 +- .../java/server/config/custom_click_action.rs | 23 +- .../src/java/server/config/keep_alive.rs | 5 +- .../src/java/server/config/known_packs.rs | 5 +- .../src/java/server/config/plugin_message.rs | 18 +- .../server/config/resource_pack_response.rs | 5 +- .../src/java/server/handshake/mod.rs | 6 +- .../src/java/server/login/cookie_response.rs | 17 +- .../java/server/login/encryption_response.rs | 26 +- .../src/java/server/login/login_response.rs | 8 +- .../src/java/server/login/login_start.rs | 6 +- .../src/java/server/login/plugin_response.rs | 8 +- .../src/java/server/play/attack.rs | 5 +- .../java/server/play/bundle_item_selected.rs | 5 +- .../src/java/server/play/change_game_mode.rs | 5 +- .../src/java/server/play/chat_command.rs | 13 +- .../src/java/server/play/chat_message.rs | 30 +- .../src/java/server/play/chunk_batch.rs | 5 +- .../src/java/server/play/click_container.rs | 12 +- .../src/java/server/play/client_command.rs | 5 +- .../java/server/play/client_information.rs | 13 +- .../src/java/server/play/close_container.rs | 5 +- .../java/server/play/command_suggestion.rs | 13 +- .../src/java/server/play/confirm_teleport.rs | 5 +- .../server/play/container_button_click.rs | 5 +- .../src/java/server/play/cookie_response.rs | 18 +- .../java/server/play/custom_click_action.rs | 18 +- .../src/java/server/play/custom_payload.rs | 18 +- .../src/java/server/play/interact.rs | 6 +- .../src/java/server/play/jigsaw_generate.rs | 5 +- .../src/java/server/play/keep_alive.rs | 5 +- .../src/java/server/play/move_vehicle.rs | 5 +- .../src/java/server/play/paddle_boat.rs | 5 +- .../src/java/server/play/pick_item.rs | 9 +- .../src/java/server/play/ping_request.rs | 5 +- .../src/java/server/play/place_recipe.rs | 5 +- .../src/java/server/play/player_abilities.rs | 5 +- .../src/java/server/play/player_action.rs | 5 +- .../src/java/server/play/player_command.rs | 6 +- .../src/java/server/play/player_ground.rs | 5 +- .../src/java/server/play/player_input.rs | 5 +- .../src/java/server/play/player_loaded.rs | 5 +- .../src/java/server/play/player_position.rs | 5 +- .../server/play/player_position_rotation.rs | 5 +- .../src/java/server/play/player_rotation.rs | 5 +- .../src/java/server/play/player_session.rs | 16 +- .../play/recipe_book_change_settings.rs | 5 +- .../server/play/recipe_book_seen_recipe.rs | 5 +- .../src/java/server/play/rename_item.rs | 13 +- .../src/java/server/play/seen_advancement.rs | 11 +- .../src/java/server/play/select_trade.rs | 5 +- .../src/java/server/play/set_beacon.rs | 5 +- .../src/java/server/play/set_command_block.rs | 13 +- .../src/java/server/play/set_creative_slot.rs | 4 +- .../src/java/server/play/set_held_item.rs | 5 +- .../src/java/server/play/set_jigsaw_block.rs | 29 +- .../src/java/server/play/set_test_block.rs | 15 +- .../src/java/server/play/swing_arm.rs | 5 +- .../java/server/play/teleport_to_entity.rs | 5 +- .../server/play/test_instance_block_action.rs | 27 +- .../src/java/server/play/update_sign.rs | 26 +- .../src/java/server/play/use_item.rs | 5 +- .../src/java/server/play/use_item_on.rs | 5 +- .../src/java/server/status/ping_request.rs | 5 +- .../src/java/server/status/status_request.rs | 5 +- pumpkin-protocol/src/lib.rs | 4 +- pumpkin-protocol/src/ser/mod.rs | 286 +++++-- pumpkin-protocol/src/serial/deserializer.rs | 159 ++++ pumpkin-protocol/src/serial/mod.rs | 29 + pumpkin-protocol/src/serial/serializer.rs | 7 + pumpkin-util/src/text/color.rs | 8 +- pumpkin-util/src/text/mod.rs | 50 +- pumpkin-world/Cargo.toml | 2 +- pumpkin-world/src/chunk/format/mod.rs | 14 +- pumpkin-world/src/chunk/format/pump.rs | 4 +- pumpkin-world/src/world_info/anvil.rs | 2 +- pumpkin/src/command/snbt/tests.rs | 20 +- pumpkin/src/entity/player.rs | 6 +- pumpkin/src/net/bedrock/mod.rs | 10 +- pumpkin/src/net/bedrock/play.rs | 19 +- pumpkin/src/net/java/config.rs | 10 +- pumpkin/src/net/java/login.rs | 2 +- pumpkin/src/net/java/mod.rs | 248 +++--- pumpkin/src/net/java/play.rs | 80 +- .../wasm_host/wit/v0_1/generated_packets.rs | 86 +- pumpkin/src/world/mod.rs | 22 +- 116 files changed, 2249 insertions(+), 1468 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9db0060d4..a42d4c220 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: include: - - os: ubuntu-24.04-arm + - os: ubuntu-26.04-arm platform: linux/arm64 - os: ubuntu-latest platform: linux/amd64 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 643bbf637..e69648c8b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -82,11 +82,10 @@ jobs: os: [ ubuntu-latest, - ubuntu-24.04-arm, + ubuntu-26.04-arm, windows-latest, windows-11-arm, macos-latest, - macos-15-intel, ] toolchain: - stable @@ -114,7 +113,6 @@ jobs: windows-latest, windows-11-arm, macos-latest, - macos-15-intel, ] toolchain: - stable diff --git a/Cargo.lock b/Cargo.lock index 06bc7ee9b..a525de8e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,15 +58,6 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anes" version = "0.1.6" @@ -81,9 +72,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arbitrary" @@ -114,13 +105,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -193,18 +184,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25655df2c3cdd83c5e5b293b88acd880332b2ddadd7c30ac43144fdc0033da9" + [[package]] name = "base64ct" version = "1.8.3" @@ -246,9 +237,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" [[package]] name = "byteorder" @@ -270,72 +261,46 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cap-fs-ext" -version = "3.4.5" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5528f85b1e134ae811704e41ef80930f56e795923f866813255bc342cc20654" +checksum = "d78e5a3368ae89b7cb68186411452b4b9fac8b41be9c19bf3f47c2d2c8e36e6b" dependencies = [ "cap-primitives", "cap-std", - "io-lifetimes", - "windows-sys 0.59.0", -] - -[[package]] -name = "cap-net-ext" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20a158160765c6a7d0d8c072a53d772e4cb243f38b04bfcf6b4939cfbe7482e7" -dependencies = [ - "cap-primitives", - "cap-std", - "rustix", - "smallvec", + "io-lifetimes 3.0.1", + "windows-sys 0.61.2", ] [[package]] name = "cap-primitives" -version = "3.4.5" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cf3aea8a5081171859ef57bc1606b1df6999df4f1110f8eef68b30098d1d3a" +checksum = "cdadbd7c002d3a484b35243669abdae85a0ebaded5a61117169dc3400f9a7ff0" dependencies = [ "ambient-authority", "fs-set-times", "io-extras", - "io-lifetimes", + "io-lifetimes 3.0.1", "ipnet", "maybe-owned", "rustix", "rustix-linux-procfs", - "windows-sys 0.59.0", + "windows-sys 0.61.2", "winx", ] [[package]] name = "cap-std" -version = "3.4.5" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6dc3090992a735d23219de5c204927163d922f42f575a0189b005c62d37549a" +checksum = "7281235d6e96d3544ca18bba9049be92f4190f8d923e3caef1b5f66cfa752608" dependencies = [ "cap-primitives", "io-extras", - "io-lifetimes", + "io-lifetimes 3.0.1", "rustix", ] -[[package]] -name = "cap-time-ext" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def102506ce40c11710a9b16e614af0cde8e76ae51b1f48c04b8d79f4b671a80" -dependencies = [ - "ambient-authority", - "cap-primitives", - "iana-time-zone", - "once_cell", - "rustix", - "winx", -] - [[package]] name = "cast" version = "0.3.0" @@ -344,9 +309,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.66" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" +checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8" dependencies = [ "find-msvc-tools", "jobserver", @@ -377,9 +342,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" @@ -432,18 +397,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstyle", "clap_lex", @@ -476,7 +441,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -485,7 +450,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -579,17 +544,11 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - [[package]] name = "cpp_demangle" -version = "0.4.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" +checksum = "0667304c32ea56cb4cd6d2d7c0cfe9a2f8041229db8c033af7f8d69492429def" dependencies = [ "cfg-if", ] @@ -620,27 +579,27 @@ dependencies = [ [[package]] name = "cranelift-assembler-x64" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06aeba2c965fc446d13c56a6ccb2631b78445d7544543dd9a25289977630914" +checksum = "8f0435c6939d6ef218bf0a3063094f2cc5c46f7a44a88f81cf932da8d3922ff8" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2d2dde4ec1352715595b5cfa6fe2e5b8ebb9da3457b3ee8db0aa2808c069aa" +checksum = "aca52511cc21a2c9c927aef493d11c8087bdc5483249a3d93aee41e81b8bd4d1" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4982ef9fa54ec9eee841e891e7ddc5434be1250e88de31572e000c888f30b" +checksum = "6867e99f068454b0c81c50b807af88aa80aaf383105e2be26675d81fc4278466" dependencies = [ "cranelift-entity", "wasmtime-internal-core", @@ -648,9 +607,9 @@ dependencies = [ [[package]] name = "cranelift-bitset" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529143118c4eeb58c39ecb02319557d512be6c61348486422974ab8e3906b8a8" +checksum = "3cf66017aed971344230199ad35ca01c955cf824a0e65fed5240452d2a302445" dependencies = [ "serde", "serde_derive", @@ -659,9 +618,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7780677247ad3577e3a6a3ebf43f39b325a11d6393db72b2c9968a910d4d13d" +checksum = "933b2e5237665bf9367a34ad2100eed70c94b2796586cb09d9ba11693e061667" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -690,9 +649,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9645250416cbf92454fe61160e17e026e0ce405906a54500b114f923ddffc9" +checksum = "322e3ca0603683cc17f0c808559c0fb85ad52b0f20ace0478bdd4ba2fa1e9678" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -703,24 +662,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ee8d222ff0fd3681791979afbf88586ac9f49010d3db96b3cbe4c96759aee3" +checksum = "287ab88211d049178dc8dda243e2db176919d8b29db605c0efc7c6d76ebea0f7" [[package]] name = "cranelift-control" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591abe6f5312bd2c4220f1b3bead56c2ad00257c52668015ba013b85dcf2a17a" +checksum = "c11438f9becf9a1e1e061bf76a33241b941a07ed01a489e9dad5fa79dc3624e9" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5300c49cf940526fe771517b3b3eabd5d0ff164ee61698579cf403fe8d3af3c" +checksum = "584ecabe1462593a9cba9efbf9022e0987421ddb548989b455ab8bdd444b743c" dependencies = [ "cranelift-bitset", "serde", @@ -730,9 +689,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4adbf760207fdbbe130f1191cce01cdef66831a9f648b1f39ff2800d126d45" +checksum = "34249873145213a12106d5fd8a98a9dc9e90e16525e2337b2907874d1e7e9ee7" dependencies = [ "cranelift-codegen", "hashbrown 0.17.1", @@ -743,15 +702,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8315b21ff018226a42a60a4702c2dd75f6447cac26e9bca622e14c22088c2ff5" +checksum = "b6f1c1dc4d6b4bc4f0be12b08cee0e59f7610287827aa62590f8e9ec6f45dff4" [[package]] name = "cranelift-native" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d506ef23a60715bde451b06620b14402166ded3b648454fccbf04f3e46a4aa70" +checksum = "31d9e4f6d9a3777b1ffa818000b4a6d7afd1b8787af71a9c58d94baef9076ced" dependencies = [ "cranelift-codegen", "libc", @@ -760,9 +719,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.133.1" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ed47e602652e3410f9387fc0db70fefadcee4d78a78881421aabcab4e26b89" +checksum = "4155f8a1afdef96a0272c67804926eee4ef35f9708ab22ad6878d4c9543df596" [[package]] name = "crc-fast" @@ -771,7 +730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e75b2483e97a5a7da73ac68a05b629f9c53cff58d8ed1c77866079e18b00dba5" dependencies = [ "digest 0.10.7", - "spin 0.10.0", + "spin 0.10.1", ] [[package]] @@ -1047,7 +1006,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1131,7 +1090,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1147,7 +1106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1158,9 +1117,9 @@ checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "fdeflate" @@ -1230,7 +1189,7 @@ version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94e7099f6313ecacbe1256e8ff9d617b75d1bcb16a6fddef94866d225a01a14a" dependencies = [ - "io-lifetimes", + "io-lifetimes 2.0.4", "rustix", "windows-sys 0.59.0", ] @@ -1246,9 +1205,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" dependencies = [ "futures-channel", "futures-core", @@ -1261,9 +1220,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" dependencies = [ "futures-core", "futures-sink", @@ -1271,15 +1230,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" dependencies = [ "futures-core", "futures-task", @@ -1288,38 +1247,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" dependencies = [ "futures-channel", "futures-core", @@ -1452,11 +1411,11 @@ dependencies = [ [[package]] name = "hdrhistogram" -version = "7.5.4" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +checksum = "f49d1053f4708f0af3cf9fc5bffc7e68a914a3c45becb231c80068c9c3f78bea" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "byteorder", "flate2", "nom", @@ -1473,7 +1432,7 @@ dependencies = [ "hash32", "rustc_version", "serde", - "spin 0.9.8", + "spin 0.9.9", "stable_deref_trait", ] @@ -1513,9 +1472,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1523,9 +1482,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" dependencies = [ "bytes", "futures-core", @@ -1565,9 +1524,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", @@ -1618,30 +1577,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icu_collections" version = "2.2.0" @@ -1807,12 +1742,12 @@ dependencies = [ [[package]] name = "io-extras" -version = "0.18.4" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2285ddfe3054097ef4b2fe909ef8c3bcd1ea52a8f0d274416caebeef39f04a65" +checksum = "20fd6de4ccfcc187e38bc21cfa543cb5a302cb86a8b114eb7f0bf0dc9f8ac00f" dependencies = [ - "io-lifetimes", - "windows-sys 0.59.0", + "io-lifetimes 3.0.1", + "windows-sys 0.60.2", ] [[package]] @@ -1821,6 +1756,12 @@ version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06432fb54d3be7964ecd3649233cddf80db2832f47fec34c01f65b3d9d774983" +[[package]] +name = "io-lifetimes" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0fb0570afe1fed943c5c3d4102d5358592d8625fda6a0007fdbe65a92fba96" + [[package]] name = "ipnet" version = "2.12.0" @@ -1915,9 +1856,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libloading" @@ -2057,12 +1998,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2075,9 +2010,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "log", @@ -2109,12 +2044,11 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.3" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" dependencies = [ "memchr", - "minimal-lexical", ] [[package]] @@ -2159,7 +2093,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2180,13 +2114,13 @@ checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "e4e98dc3b890f6c23a0f9d3d491a2823d0dea0fa656302a13dd225fa924112a8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -2332,9 +2266,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.7" +version = "2.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9" +checksum = "7df728be843c7070fab6ab7c328c4e9e9d78e23bf749c0669c86ee7ebfa050a2" dependencies = [ "memchr", "ucd-trie", @@ -2342,9 +2276,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.7" +version = "2.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4254325ecad416ab689e27ba51da03ba01a9632bc6e108f5fe7c3c4ad29d58" +checksum = "9e2dd6fc3b26b3462ee188aac870f5a41d398f1cd5e2408d16531bd71c9591fd" dependencies = [ "pest", "pest_generator", @@ -2352,22 +2286,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.7" +version = "2.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c4c0e91ead7a8f7acecbca6f003fc2e8282b1dbe2dd9c9d2f16aba42995e0a7" +checksum = "6a7a9205cfb6f596a9e8b689c0a15f9ceb7a1aafae7aaf788150ac65b29975b6" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "pest_meta" -version = "2.8.7" +version = "2.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9744bc48116fee06334924bb5f2bad41eed5e89bd26e29b0b799f9a3f82c210" +checksum = "85abd351c0de1e8384fc791a0737111a350394937e92b956b743dac12429f57c" dependencies = [ "pest", ] @@ -2403,7 +2337,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2432,7 +2366,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2520,7 +2454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2573,9 +2507,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2600,7 +2534,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2614,9 +2548,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b92604caae1a1899b6a5b54967289dd538177c626004c91accf9d0ec7e4a12" +checksum = "f6064e52588328c1275d690baad99f8d4b3fdd870736966f1a63cfcbb20560b6" dependencies = [ "cranelift-bitset", "log", @@ -2626,13 +2560,13 @@ dependencies = [ [[package]] name = "pulley-macros" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a7ac85c0bb3fb351f10d531230aaa5e366b46d7c4e5328e5f02801d6dac1165" +checksum = "7e832980317bfc7f8c8538ffc9c69b82912f3e33ec70f7c855d521654c70fa62" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2640,7 +2574,7 @@ name = "pumpkin" version = "0.1.0-dev+26.2" dependencies = [ "arc-swap", - "base64 0.22.1", + "base64 0.23.0", "bitflags", "bytes", "colored", @@ -2680,7 +2614,7 @@ dependencies = [ "sha2 0.11.0", "sysinfo", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "time", "tokio", "tokio-util", @@ -2701,14 +2635,13 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 3.0.0", + "syn 3.0.3", ] [[package]] name = "pumpkin-codecs" version = "0.1.0-dev+26.2" dependencies = [ - "either", "serde_json", "tracing", ] @@ -2719,7 +2652,7 @@ version = "0.1.0-dev+26.2" dependencies = [ "pumpkin-util", "serde", - "toml 1.1.2+spec-1.1.0", + "toml 1.1.3+spec-1.1.0", "tracing", "uuid", ] @@ -2746,7 +2679,7 @@ dependencies = [ "pumpkin-util", "pumpkin-world", "rand", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tracing", ] @@ -2759,7 +2692,7 @@ dependencies = [ "proc-macro-error2", "pumpkin-data", "quote", - "syn 3.0.0", + "syn 3.0.3", ] [[package]] @@ -2773,7 +2706,7 @@ dependencies = [ "pumpkin-codecs", "serde", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tracing", "uuid", ] @@ -2808,7 +2741,7 @@ dependencies = [ "pumpkin-world", "serde", "sha2 0.11.0", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "uuid", ] @@ -2817,7 +2750,7 @@ dependencies = [ name = "pumpkin-util" version = "0.1.0-dev+26.2" dependencies = [ - "base64 0.22.1", + "base64 0.23.0", "bytes", "colored", "crypto-bigint", @@ -2835,8 +2768,8 @@ dependencies = [ "serde", "serde_json", "sha2 0.11.0", - "syn 3.0.0", - "thiserror 2.0.18", + "syn 3.0.3", + "thiserror 2.0.19", "tokio", "ureq", "uuid", @@ -2871,8 +2804,8 @@ dependencies = [ "serde_json5", "sha2 0.11.0", "slotmap", - "temp-dir", - "thiserror 2.0.18", + "tempfile", + "thiserror 2.0.19", "tokio", "tokio-util", "tracing", @@ -2888,9 +2821,9 @@ checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -2960,9 +2893,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2c52737737f8609e94f975dee22854a2d5c125772d4b1cf292120f4d45c186" +checksum = "757712e8e61590d6d4f5d563483755538b5aa13467837a3b41cd9832509a7f85" dependencies = [ "allocator-api2", "bumpalo", @@ -2975,9 +2908,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -2987,9 +2920,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -3085,7 +3018,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3100,9 +3033,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.41" +version = "0.23.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" dependencies = [ "log", "once_cell", @@ -3115,9 +3048,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "zeroize", ] @@ -3205,9 +3138,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -3215,29 +3148,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -3259,13 +3192,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -3357,9 +3290,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "siphasher" @@ -3393,28 +3326,28 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" [[package]] name = "spki" @@ -3446,9 +3379,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -3457,9 +3390,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.0" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fac314a64dc9a36e61a9eb4261a5e9bbfbc922b27e518af97bc32b926cf967" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -3480,7 +3413,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3503,12 +3436,6 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" -[[package]] -name = "temp-dir" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016ef9739649996fcc983b9c588fe3d557cf216d4d98503ce1b057ab5a66d689" - [[package]] name = "tempfile" version = "3.27.0" @@ -3518,7 +3445,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3541,11 +3468,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.19", ] [[package]] @@ -3556,34 +3483,34 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "time" -version = "0.3.53" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" +checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244" dependencies = [ "deranged", "libc", @@ -3603,9 +3530,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -3633,9 +3560,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.53.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -3650,13 +3577,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3671,9 +3598,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -3682,14 +3609,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", "futures-util", + "libc", "pin-project-lite", "tokio", ] @@ -3711,16 +3639,16 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c" dependencies = [ "serde_core", "serde_spanned", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -3747,14 +3675,14 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" @@ -3846,7 +3774,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3934,12 +3862,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "untrusted" version = "0.9.0" @@ -3962,7 +3884,7 @@ dependencies = [ "serde_json", "ureq-proto", "utf8-zero", - "webpki-roots 1.0.8", + "webpki-roots", ] [[package]] @@ -4089,7 +4011,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wasm-bindgen-shared", ] @@ -4104,41 +4026,41 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.251.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a879a421bd17c528b74721b2abf4c62e8f1d1889c2ba8c3c50d02deaf2ce395" +checksum = "8185ae345fa5687c054626ff9a50e7089797a343d9904d1dc9820eb4c4d3196f" dependencies = [ "leb128fmt", - "wasmparser 0.251.0", + "wasmparser 0.252.0", ] [[package]] name = "wasm-encoder" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59972d6cd272259de647b7c1f1912e45e289c75ffd4be04e10695507cd7e1b59" +checksum = "09480d646178e5fdd12bb06e812d0af9a3a191dbc9cd697fdc86687beade7393" dependencies = [ "leb128fmt", - "wasmparser 0.253.0", + "wasmparser 0.254.0", ] [[package]] name = "wasm-metadata" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f45816ef616806f48498bcd831377de578c4fa51db0c83ab8ceb78cc13523b" +checksum = "b01df5f3b4ca7881e843f3bc0fb8a3905d79c68692250dcb8e33e698705ccdb6" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.253.0", - "wasmparser 0.253.0", + "wasm-encoder 0.254.0", + "wasmparser 0.254.0", ] [[package]] name = "wasmparser" -version = "0.251.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437970b35b1a85cfde9c74b2398352d8d653f3bd8e3a3db0c063ea8f5b4b36ff" +checksum = "d3eb099dcadcde5be9eef55e3a337128efd4e44b4c93122487e4d2e4e1c6627c" dependencies = [ "bitflags", "hashbrown 0.17.1", @@ -4149,9 +4071,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19db11f87d2486580e1e8b6f494c54df7e0566b87d0b599db843c24019667339" +checksum = "d5769a29f799fbab136aaf65b4fe5384cd7d93fe6fc9ba0dcb6c8382a1f16e27" dependencies = [ "bitflags", "hashbrown 0.17.1", @@ -4161,20 +4083,20 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.251.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8798c1a699bd25648b6708eefe94d97c6f9891febb94b42cca1f7a4b086ea64e" +checksum = "7142797de29b35ab8dbf15c00f55fda75d409da4c423a8ab8bd6b667a785824b" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.251.0", + "wasmparser 0.252.0", ] [[package]] name = "wasmtime" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4213d2f019a5e44aa8a61d8826dd33a505bff79f749b14a8bafd67321cb9351" +checksum = "06d9f263ccb212017dae1d109b9997f218a7675db1e9a7bedf07ae1643322bf3" dependencies = [ "addr2line", "async-trait", @@ -4198,7 +4120,7 @@ dependencies = [ "serde_derive", "smallvec", "target-lexicon", - "wasmparser 0.251.0", + "wasmparser 0.252.0", "wasmtime-environ", "wasmtime-internal-cache", "wasmtime-internal-component-macro", @@ -4215,9 +4137,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45863de41977ec6453e859cf843d456fa3fcb45a659b66d16e794f90ec4f5b7" +checksum = "9915e3d90c36a16e0fec8be746ee87e21cf0d4a017ecf09c49b7d1cc6f31b2b6" dependencies = [ "anyhow", "cpp_demangle", @@ -4237,8 +4159,8 @@ dependencies = [ "sha2 0.10.9", "smallvec", "target-lexicon", - "wasm-encoder 0.251.0", - "wasmparser 0.251.0", + "wasm-encoder 0.252.0", + "wasmparser 0.252.0", "wasmprinter", "wasmtime-internal-component-util", "wasmtime-internal-core", @@ -4246,9 +4168,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-cache" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438bc7dc45fb75297d75f79a9a0ce852345d13ebc6a6863f6f688f013836a9dd" +checksum = "6b7c25436e1602aad2de80bfb3f586dcdfb6fe426d5b17cba37fabf9a1714d32" dependencies = [ "base64 0.22.1", "directories-next", @@ -4266,30 +4188,30 @@ dependencies = [ [[package]] name = "wasmtime-internal-component-macro" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e48f8d4966d62a10b6d70722bc432c1e163890be2801d3b5784589ad36ffc3" +checksum = "b627ea698db36fb9110aa77868467f1d23791a76a88a433cb6a43e1242073b77" dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wasmtime-internal-component-util", "wasmtime-internal-wit-bindgen", - "wit-parser 0.251.0", + "wit-parser 0.252.0", ] [[package]] name = "wasmtime-internal-component-util" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819ad5abd5822a22dbf4014475cdfd1fe790707761cd732d74aaa3ba4d5ba489" +checksum = "f45bf943cff1d2f1976bac6a241ca4ecaf29a6efd5f1ad89e7722439fa5c392f" [[package]] name = "wasmtime-internal-core" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc28372e36eaf8cf70faa83b5779137f7e99c8d18569a125d1580e735cc9e4d" +checksum = "ea33e1f9685be82f90223bebcf2ffefb6b596ea3d82a3c42384527b9c6f5b447" dependencies = [ "hashbrown 0.17.1", "libm", @@ -4298,9 +4220,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-cranelift" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a433efc6e35112a5457e1dc8bc4d8d39820ac7722267e89bc04e5df641f32124" +checksum = "8b1ce104719932a48dbdfec0cc292c96494b0bfe764946e45fbfd3340e3a68f9" dependencies = [ "cfg-if", "cranelift-codegen", @@ -4315,8 +4237,8 @@ dependencies = [ "pulley-interpreter", "smallvec", "target-lexicon", - "thiserror 2.0.18", - "wasmparser 0.251.0", + "thiserror 2.0.19", + "wasmparser 0.252.0", "wasmtime-environ", "wasmtime-internal-core", "wasmtime-internal-unwinder", @@ -4325,9 +4247,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-fiber" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a1d3a39d0d210f6b8574ee96a4315e0a14c67f3a1fc3cd5372cb10d2fb4422" +checksum = "976e4b71b9c0da8a9a7bb8d5fa0abedc4da879b397111fd91ece73be524fe621" dependencies = [ "cc", "cfg-if", @@ -4340,9 +4262,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-debug" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f667288cb4dfa68a4639ffac4d5628535dda64ebdc2b990526efb12b30ba803" +checksum = "f1f60ecba3497cfc26284903c2e79023fd5ea991b95b0e8dafe994fd9fca4c4e" dependencies = [ "cc", "wasmtime-internal-versioned-export-macros", @@ -4350,9 +4272,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba651d44ab0faad4c58106b3adb45068189fb65ef50f0c404b6d9e3bf81a357" +checksum = "fae6decb025ae6d12f3391b36deb62a6838d45b18864f796d84bced722ceac0d" dependencies = [ "cfg-if", "libc", @@ -4362,9 +4284,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-unwinder" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ecc52563b0558af2a7487eb710de07cc4532564b55528876129238e83118cb1" +checksum = "0982122d9470d3d72ed7aa9ed91e69538ae44c1494cd22d78fec7846b248a940" dependencies = [ "cfg-if", "cranelift-codegen", @@ -4375,48 +4297,45 @@ dependencies = [ [[package]] name = "wasmtime-internal-versioned-export-macros" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e747f4a074699ba1b4e4d841fb263f9b7df5bd1555181c4752bf5990d21ba676" +checksum = "363cf88a80e6ed13311d0d34d9bcd02a2e07d98113b994ff41ed386a206f498e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "wasmtime-internal-wit-bindgen" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80009f46991622814196d96fac6fc0a938f46b5cba737a8f4e21e24e5a03856f" +checksum = "87ff41bb1656cbeb7befc42b8a7078b30a5f8393a0c8bca36a6cec94360c1a16" dependencies = [ "anyhow", "bitflags", "heck", "indexmap", - "wit-parser 0.251.0", + "wit-parser 0.252.0", ] [[package]] name = "wasmtime-wasi" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f65ef30a2c5478873cdb619085a7a649d3ce41cc3eaf298a7ce3dee96a8e11" +checksum = "ed1750b8e5e5d5b1ee3c0eb602d2c49d6a37a36e9996eaf0708b48ac92b62b06" dependencies = [ "async-trait", "bitflags", "bytes", "cap-fs-ext", - "cap-net-ext", "cap-std", - "cap-time-ext", "cfg-if", "futures", - "io-extras", - "io-lifetimes", + "io-lifetimes 3.0.1", "rand", "rustix", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tracing", "url", @@ -4427,9 +4346,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi-http" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb65eeb8116615c2a22f51b19672c0d5b652ca7b051086da5c7c0a9eb39f4af7" +checksum = "014b8f05cacb7a5d665536e8a733b887bd192a9c179037580d48d0a6a82ecd34" dependencies = [ "async-trait", "bytes", @@ -4445,14 +4364,14 @@ dependencies = [ "wasmtime", "wasmtime-wasi", "wasmtime-wasi-io", - "webpki-roots 0.26.11", + "webpki-roots", ] [[package]] name = "wasmtime-wasi-io" -version = "46.0.1" +version = "47.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee57d5fef4976b1ab542615f4cef2c43278eb549d8078939668ea0f13d5c696" +checksum = "54777d3afeaf3f32cc444df661d9cb4fd57067971e183c2b1f5251f33b939e68" dependencies = [ "async-trait", "bytes", @@ -4463,18 +4382,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.8", -] - -[[package]] -name = "webpki-roots" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] @@ -4501,7 +4411,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4563,7 +4473,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -4574,7 +4484,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -4793,9 +4703,9 @@ checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "winx" @@ -4809,35 +4719,35 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c5e45f6d4cfaca727c1c48989ab3e05bb289bf84fbad226e1cfbbef2c04b7f" +checksum = "a301904d6657d6364c758d869e5389d05d393b16d5b65db60b4f03cbe71bb80d" dependencies = [ "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen-core" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cf25dc4bb1981c16aa549ec66c6762b7752bfb8b7c3b3936ae13100298dc72" +checksum = "48521bb96e56cbb9e031ad306c80dc20e89e69e49ada02781ee06f60fbcb545f" dependencies = [ "anyhow", "heck", - "wit-parser 0.253.0", + "wit-parser 0.254.0", ] [[package]] name = "wit-bindgen-rust" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "407ee2b474af1a366766fe91b8255b7935e5e3c3afb9c304e91ac3d154287ff1" +checksum = "3df3fe9b9a0066f82fd0c2f07f79d0ffc0f85c53fa5f998516d8722712479042" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -4845,24 +4755,24 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37386eba32427684ffe37a0f765f63ce2ece03efb1ad28c23cf69562fdc67ec0" +checksum = "d689c4bc9d6af067c651cfba444766343c9a4bdef15fad1e2efab95c0c277af0" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] [[package]] name = "wit-component" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbd2500ac3488489ee8c6e59b79d7e47e6da5bfb019efd35d5dca57b78af624" +checksum = "b0e65bb94c369b3c4741ce3d1d2704b1fec93db7c540df0e521a097e7ceeb5be" dependencies = [ "anyhow", "bitflags", @@ -4871,36 +4781,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.253.0", + "wasm-encoder 0.254.0", "wasm-metadata", - "wasmparser 0.253.0", - "wit-parser 0.253.0", + "wasmparser 0.254.0", + "wit-parser 0.254.0", ] [[package]] name = "wit-parser" -version = "0.251.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e960732e824fab95099971a09e638979347c94ca48568d3c854c945729196947" -dependencies = [ - "anyhow", - "hashbrown 0.17.1", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.251.0", -] - -[[package]] -name = "wit-parser" -version = "0.253.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d997b8e5920fcbeec742b58e583325d6419a6aca617ae8075c406a61c65ba8a" +checksum = "4266bea110371c620ccf3201c5023676046bc4556e5c7cfb5d500bda5ebc162d" dependencies = [ "anyhow", "hashbrown 0.17.1", @@ -4912,7 +4803,26 @@ dependencies = [ "serde_derive", "serde_json", "unicode-ident", - "wasmparser 0.253.0", + "wasmparser 0.252.0", +] + +[[package]] +name = "wit-parser" +version = "0.254.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1655131e4f7d3f0cb141f6eca71315ca40eff0f3d4de7cff0a82bacedd8c89b4" +dependencies = [ + "anyhow", + "hashbrown 0.17.1", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-ident", + "wasmparser 0.254.0", ] [[package]] @@ -4934,9 +4844,9 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xxhash-rust" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d93c89cdc2d3a63c3ec48ffe926931bdc069eafa8e4402fe6d8f790c9d1e576" +checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6" [[package]] name = "yoke" @@ -4957,28 +4867,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.54" +version = "0.8.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" +checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.54" +version = "0.8.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" +checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -4998,7 +4908,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "synstructure", ] @@ -5038,14 +4948,14 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 9dc2096ed..7667ee64d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,7 +119,7 @@ tempfile = { version = "3.27.0", default-features = false } proc-macro-error2 = { version = "2", default-features = false } aes = { version = "0.9", default-features = false } async-compression = { version = "0.4.42", default-features = false } -base64 = { version = "0.22.1", default-features = false, features = ["std"] } +base64 = { version = "0.23.0", default-features = false, features = ["std"] } bitflags = { version = "2.13.1", default-features = false, features = ["std"] } cesu8 = { version = "1.1", default-features = false } cfb8 = { version = "0.9", default-features = false } @@ -133,7 +133,6 @@ crossfire = { version = "3.1.19", default-features = false, features = ["compat" crypto-bigint = { version = "0.7.5", default-features = false } dashmap = { version = "6.2", default-features = false } ecdsa = { version = "0.17.0", default-features = false, features = ["std"] } -either = { version = "1.16.0", default-features = false } enum_dispatch = { version = "0.3.13", default-features = false } flate2 = { version = "1.1.9", default-features = false, features = ["rust_backend"] } heck = { version = "0.5", default-features = false } @@ -145,7 +144,7 @@ lru = { version = "0.18.1", default-features = false } lz4-java-wrc = { version = "0.2.0", default-features = false, features = ["lz4_flex"] } md5 = { version = "0.8", default-features = false } num-bigint = { version = "0.5", default-features = false, features = ["std"] } -num-derive = { version = "0.4", default-features = false } +num-derive = { version = "0.5", default-features = false } num-traits = { version = "0.2", default-features = false, features = ["std"] } p384 = { version = "0.14.0", default-features = false, features = ["std", "arithmetic", "pkcs8", "ecdh"] } phf = { version = "0.14.0", default-features = false, features = ["std"] } @@ -178,11 +177,9 @@ tracing-subscriber = { version = "0.3.23", default-features = false, features = "std", ] } slotmap = { version = "1.1", default-features = false, features = ["std"] } -temp-dir = { version = "0.2.0", default-features = false } -thread_local = { version = "1.1.10", default-features = false } time = { version = "0.3", default-features = false, features = ["std"] } arc-swap = { version = "1.9", default-features = false } -tokio-util = { version = "0.7.18", default-features = false } +tokio-util = { version = "0.7.19", default-features = false } toml = { version = "1.1", default-features = false, features = ["parse", "display", "serde"] } ureq = { version = "3.3.0", default-features = false, features = ["rustls"] } notify = { version = "8.2.0", default-features = false, features = ["macos_fsevent"] } @@ -192,12 +189,12 @@ rustc_version_runtime = { version = "0.3", default-features = false } ordered-float = { version = "5.3", default-features = false, features = ["std"] } xxhash-rust = { version = "0.8", default-features = false, features = ["xxh64"] } -wasmtime = { version = "46.0", default-features = false, features = ["runtime", "component-model", "async", "cache", "cranelift", "gc", "gc-drc", "threads", "std"] } -wasmtime-wasi = { version = "46.0", default-features = false, features = ["p2"] } -wasmtime-wasi-http = { version = "46.0", default-features = false, features = ["p2", "default-send-request"] } +wasmtime = { version = "47.0", default-features = false, features = ["runtime", "component-model", "async", "cache", "cranelift", "gc", "gc-drc", "threads", "std"] } +wasmtime-wasi = { version = "47.0", default-features = false, features = ["p2"] } +wasmtime-wasi-http = { version = "47.0", default-features = false, features = ["p2", "default-send-request"] } # needed for interacting with wasmtime-wasi-http - keep in sync -hyper = { version = "^1.10", default-features = false } -wit-bindgen = { version = "0.59", default-features = false, features = ["macros"] } +hyper = { version = "^1.11", default-features = false } +wit-bindgen = { version = "0.60", default-features = false, features = ["macros"] } postcard = { version = "1.1", default-features = false, features = ["alloc"] } tracing-serde-structured = { version = "0.4", default-features = false } diff --git a/pumpkin-codecs/Cargo.toml b/pumpkin-codecs/Cargo.toml index a0f81a991..bb6e57589 100644 --- a/pumpkin-codecs/Cargo.toml +++ b/pumpkin-codecs/Cargo.toml @@ -8,7 +8,6 @@ license.workspace = true [dependencies] serde_json.workspace = true tracing.workspace = true -either.workspace = true [lints] workspace = true diff --git a/pumpkin-codecs/src/codec/either.rs b/pumpkin-codecs/src/codec/either.rs index 7967df859..2140a446a 100644 --- a/pumpkin-codecs/src/codec/either.rs +++ b/pumpkin-codecs/src/codec/either.rs @@ -1,5 +1,34 @@ use crate::{DataResult, Decode, DynamicOps, Encode}; -use either::Either; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Either { + Left(L), + Right(R), +} + +impl Either { + pub const fn is_left(&self) -> bool { + matches!(self, Self::Left(_)) + } + + pub const fn is_right(&self) -> bool { + matches!(self, Self::Right(_)) + } + + pub fn left(self) -> Option { + match self { + Self::Left(l) => Some(l), + Self::Right(_) => None, + } + } + + pub fn right(self) -> Option { + match self { + Self::Left(_) => None, + Self::Right(r) => Some(r), + } + } +} impl Encode for Either { fn encode(&self, ops: &'static O, prefix: O::Value) -> DataResult { @@ -46,9 +75,9 @@ impl Decode for Either { #[cfg(test)] mod test { + use super::Either; use crate::json_ops::JsonOps; use crate::{assert_decode, assert_encode_success}; - use either::Either; use serde_json::json; #[test] diff --git a/pumpkin-codecs/src/codec/mod.rs b/pumpkin-codecs/src/codec/mod.rs index c08dfacfc..aae140bc4 100644 --- a/pumpkin-codecs/src/codec/mod.rs +++ b/pumpkin-codecs/src/codec/mod.rs @@ -1,4 +1,4 @@ -mod either; +pub mod either; pub mod list; pub mod map; pub mod optional_field; diff --git a/pumpkin-codecs/src/lib.rs b/pumpkin-codecs/src/lib.rs index 3d6461588..37f4c8b2d 100644 --- a/pumpkin-codecs/src/lib.rs +++ b/pumpkin-codecs/src/lib.rs @@ -21,6 +21,7 @@ pub use number::Number; pub use crate::codec::Decode; pub use crate::codec::Encode; +pub use crate::codec::either::Either; pub use crate::codec::primitive::ByteBuffer; pub use crate::codec::primitive::IntStream; pub use crate::codec::primitive::LongStream; diff --git a/pumpkin-codegen/Cargo.lock b/pumpkin-codegen/Cargo.lock index a1078f00d..208a46b94 100644 --- a/pumpkin-codegen/Cargo.lock +++ b/pumpkin-codegen/Cargo.lock @@ -32,6 +32,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25655df2c3cdd83c5e5b293b88acd880332b2ddadd7c30ac43144fdc0033da9" + [[package]] name = "base64ct" version = "1.8.3" @@ -40,9 +46,9 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "block-buffer" @@ -324,7 +330,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -584,13 +590,13 @@ dependencies = [ [[package]] name = "num-derive" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "e4e98dc3b890f6c23a0f9d3d491a2823d0dea0fa656302a13dd225fa924112a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.2", ] [[package]] @@ -667,7 +673,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -723,7 +729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.118", ] [[package]] @@ -788,7 +794,7 @@ dependencies = [ "serde_json", "serde_json5", "serde_repr", - "syn", + "syn 3.0.2", "wit-encoder", ] @@ -800,6 +806,7 @@ dependencies = [ "cesu8", "flate2", "pumpkin-codecs", + "rustc-hash", "serde", "thiserror", "tracing", @@ -810,7 +817,7 @@ dependencies = [ name = "pumpkin-util" version = "0.1.0-dev+26.2" dependencies = [ - "base64", + "base64 0.23.0", "bytes", "colored", "crypto-bigint", @@ -828,7 +835,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.11.0", - "syn", + "syn 3.0.2", "thiserror", "tokio", "ureq", @@ -918,6 +925,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + [[package]] name = "rustls" version = "0.23.39" @@ -985,9 +998,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -995,29 +1008,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.2", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "indexmap", "itoa", @@ -1046,7 +1059,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1130,6 +1143,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "thiserror" version = "2.0.18" @@ -1147,14 +1171,14 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] name = "tokio" -version = "1.52.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "pin-project-lite", ] @@ -1178,7 +1202,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1226,7 +1250,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ - "base64", + "base64 0.22.1", "log", "percent-encoding", "rustls", @@ -1242,7 +1266,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ - "base64", + "base64 0.22.1", "http", "httparse", "log", @@ -1256,9 +1280,9 @@ checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" [[package]] name = "uuid" -version = "1.23.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ "getrandom 0.4.1", "js-sys", @@ -1329,7 +1353,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.118", "wasm-bindgen-shared", ] @@ -1378,9 +1402,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19db11f87d2486580e1e8b6f494c54df7e0566b87d0b599db843c24019667339" +checksum = "d5769a29f799fbab136aaf65b4fe5384cd7d93fe6fc9ba0dcb6c8382a1f16e27" dependencies = [ "bitflags", "indexmap", @@ -1514,7 +1538,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn", + "syn 2.0.118", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -1530,7 +1554,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.118", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -1556,15 +1580,15 @@ dependencies = [ [[package]] name = "wit-encoder" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b783601ee9357f78aaa12bc5cfd0cd0a2fb3d637de1f35604e14eef52ab97d" +checksum = "c565f1f3dcf3b659d6c15052739e35937227590d7dded3d3ce274f7bd9c34d93" dependencies = [ "id-arena", "pretty_assertions", "semver", "serde", - "wit-parser 0.253.0", + "wit-parser 0.254.0", ] [[package]] @@ -1587,9 +1611,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.253.0" +version = "0.254.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d997b8e5920fcbeec742b58e583325d6419a6aca617ae8075c406a61c65ba8a" +checksum = "1655131e4f7d3f0cb141f6eca71315ca40eff0f3d4de7cff0a82bacedd8c89b4" dependencies = [ "anyhow", "hashbrown 0.17.1", @@ -1601,7 +1625,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-ident", - "wasmparser 0.253.0", + "wasmparser 0.254.0", ] [[package]] diff --git a/pumpkin-codegen/Cargo.toml b/pumpkin-codegen/Cargo.toml index 06ebc2723..c08c0199f 100644 --- a/pumpkin-codegen/Cargo.toml +++ b/pumpkin-codegen/Cargo.toml @@ -16,13 +16,13 @@ serde_repr = { version = "0.1" } serde_json = { version = "1.0", features = ["preserve_order"] } serde_json5 = "0.2" -wit-encoder = "0.253.0" +wit-encoder = "0.254.0" semver = "1.0" rayon = "1.12.0" proc-macro2 = "1.0" quote = "1.0" -syn = { version = "2.0", features = ["full", "extra-traits"] } +syn = { version = "3.0", features = ["full", "extra-traits"] } pumpkin-util = { path = "../pumpkin-util", features = ["codegen"] } pumpkin-nbt = { path = "../pumpkin-nbt" } diff --git a/pumpkin-codegen/src/item.rs b/pumpkin-codegen/src/item.rs index eab39642c..18178e513 100644 --- a/pumpkin-codegen/src/item.rs +++ b/pumpkin-codegen/src/item.rs @@ -765,7 +765,9 @@ impl ToTokens for ItemComponents { tokens.extend(quote! { (EnchantmentGlintOverride, &EnchantmentGlintOverrideImpl), }); } if self.enchantments.is_some() { - tokens.extend(quote! { (Enchantments, &EnchantmentsImpl { enchantment: Cow::Borrowed(&[]) }), }); + tokens.extend( + quote! { (Enchantments, &EnchantmentsImpl { enchantment: Cow::Borrowed(&[]) }), }, + ); } if self.entity_data.is_some() { tokens.extend(quote! { (EntityData, &EntityDataImpl), }); @@ -793,7 +795,8 @@ impl ToTokens for ItemComponents { } if let Some(model) = &self.item_model { let model_lit = LitStr::new(model, Span::call_site()); - tokens.extend(quote! { (ItemModel, &ItemModelImpl { id: Cow::Borrowed(#model_lit) }), }); + tokens + .extend(quote! { (ItemModel, &ItemModelImpl { id: Cow::Borrowed(#model_lit) }), }); } if self.kinetic_weapon.is_some() { tokens.extend(quote! { (KineticWeapon, &KineticWeaponImpl), }); @@ -870,7 +873,9 @@ impl ToTokens for ItemComponents { tokens.extend(quote! { (UseRemainder, &UseRemainderImpl), }); } if self.writable_book_content.is_some() { - tokens.extend(quote! { (WritableBookContent, &WritableBookContentImpl { pages: Vec::new() }), }); + tokens.extend( + quote! { (WritableBookContent, &WritableBookContentImpl { pages: Vec::new() }), }, + ); } } } diff --git a/pumpkin-codegen/src/loot.rs b/pumpkin-codegen/src/loot.rs index 03cb6735b..fdd7756bb 100644 --- a/pumpkin-codegen/src/loot.rs +++ b/pumpkin-codegen/src/loot.rs @@ -538,7 +538,9 @@ impl ToTokens for LootConditionStruct { .and_then(|p| p.entity_type.as_ref()) .map(|t| match t { StringOrVec::String(s) => quote! { Some(#s) }, - StringOrVec::Vec(v) => v.first().map_or(quote! { None }, |s| quote! { Some(#s) }), + StringOrVec::Vec(v) => { + v.first().map_or(quote! { None }, |s| quote! { Some(#s) }) + } }) .unwrap_or(quote! { None }); @@ -559,7 +561,9 @@ impl ToTokens for LootConditionStruct { .and_then(|ench| ench.enchantments.as_ref()) .map(|t| match t { StringOrVec::String(s) => quote! { Some(#s) }, - StringOrVec::Vec(v) => v.first().map_or(quote! { None }, |s| quote! { Some(#s) }), + StringOrVec::Vec(v) => { + v.first().map_or(quote! { None }, |s| quote! { Some(#s) }) + } }) .unwrap_or(quote! { None }); @@ -613,7 +617,9 @@ impl ToTokens for LootConditionStruct { .and_then(|e| e.entity_type.as_ref()) .map(|t| match t { StringOrVec::String(s) => quote! { Some(#s) }, - StringOrVec::Vec(v) => v.first().map_or(quote! { None }, |s| quote! { Some(#s) }), + StringOrVec::Vec(v) => { + v.first().map_or(quote! { None }, |s| quote! { Some(#s) }) + } }) .unwrap_or(quote! { None }); @@ -623,7 +629,9 @@ impl ToTokens for LootConditionStruct { .and_then(|e| e.entity_type.as_ref()) .map(|t| match t { StringOrVec::String(s) => quote! { Some(#s) }, - StringOrVec::Vec(v) => v.first().map_or(quote! { None }, |s| quote! { Some(#s) }), + StringOrVec::Vec(v) => { + v.first().map_or(quote! { None }, |s| quote! { Some(#s) }) + } }) .unwrap_or(quote! { None }); @@ -643,7 +651,9 @@ impl ToTokens for LootConditionStruct { .and_then(|p| p.biome.as_ref()) .map(|b| match b { StringOrVec::String(s) => quote! { Some(#s) }, - StringOrVec::Vec(v) => v.first().map_or(quote! { None }, |s| quote! { Some(#s) }), + StringOrVec::Vec(v) => { + v.first().map_or(quote! { None }, |s| quote! { Some(#s) }) + } }) .unwrap_or(quote! { None }); quote! { LootCondition::LocationCheck { offset_x: #ox, offset_y: #oy, offset_z: #oz, expected_biome: #expected_biome } } diff --git a/pumpkin-codegen/src/wit/java_packet.rs b/pumpkin-codegen/src/wit/java_packet.rs index ea58906cc..8513c5bd9 100644 --- a/pumpkin-codegen/src/wit/java_packet.rs +++ b/pumpkin-codegen/src/wit/java_packet.rs @@ -165,7 +165,7 @@ fn collect_fields( .collect() } -fn wit_name(name: String,state: &str) -> String{ +fn wit_name(name: String, state: &str) -> String { if state == "play" { name.to_kebab_case() } else { @@ -180,7 +180,7 @@ fn process_struct( variant: &mut Variant, defined_cases: &mut HashSet, ) { - let wit_name = wit_name(s.ident.to_string(),state); + let wit_name = wit_name(s.ident.to_string(), state); if !defined_cases.insert(wit_name.clone()) { return; } @@ -199,7 +199,7 @@ fn process_enum( variant: &mut Variant, defined_cases: &mut HashSet, ) { - let enum_wit_name = wit_name(e.ident.to_string(),state); + let enum_wit_name = wit_name(e.ident.to_string(), state); if !defined_cases.insert(enum_wit_name.clone()) { return; } diff --git a/pumpkin-codegen/src/wit/packet_mapping.rs b/pumpkin-codegen/src/wit/packet_mapping.rs index 11e47792e..88d37a695 100644 --- a/pumpkin-codegen/src/wit/packet_mapping.rs +++ b/pumpkin-codegen/src/wit/packet_mapping.rs @@ -43,7 +43,7 @@ pub fn build_java_mapping() -> String { output.push_str("}\n\n"); output.push_str("#[must_use]\n"); - output.push_str("pub fn deserialize_java_serverbound_packet(id: i32, payload: &[u8], version: JavaMinecraftVersion) -> Option {\n"); + output.push_str("pub fn deserialize_java_serverbound_packet(id: i32, mut payload: &[u8], version: JavaMinecraftVersion) -> Option {\n"); output.push_str(" match id {\n"); for state in server_states { @@ -715,7 +715,7 @@ fn emit_struct_output( )); output.push_str(" use pumpkin_protocol::ServerPacket;\n"); output.push_str(&format!( - " let p = <{}::{} as pumpkin_protocol::ServerPacket>::read(&mut Cursor::new(payload), &version).ok()?;\n", + " let p = <{}::{} as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;\n", rust_path_prefix, struct_name )); } else { @@ -846,7 +846,7 @@ fn process_enum( )); output.push_str(" use pumpkin_protocol::ServerPacket;\n"); output.push_str(&format!( - " let p = <{}::{} as pumpkin_protocol::ServerPacket>::read(&mut Cursor::new(payload), &version).ok()?;\n", + " let p = <{}::{} as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;\n", rust_path_prefix, enum_name )); } else { diff --git a/pumpkin-nbt/benches/nbt.rs b/pumpkin-nbt/benches/nbt.rs index 301498f24..3aad04735 100644 --- a/pumpkin-nbt/benches/nbt.rs +++ b/pumpkin-nbt/benches/nbt.rs @@ -106,7 +106,7 @@ pub fn bench_nbt(c: &mut Criterion) { c.bench_function("nbt/java/deserialize/raw", |b| { b.iter(|| { - let mut cursor = Cursor::new(&wrapper_bytes_java); + let mut cursor = Cursor::new(&wrapper_bytes_java[..]); let mut reader = deserializer::NbtReadHelperJava::new(&mut cursor); Nbt::read(&mut reader).unwrap(); }); @@ -135,7 +135,7 @@ pub fn bench_nbt(c: &mut Criterion) { c.bench_function("nbt/bedrock/deserialize/raw", |b| { b.iter(|| { - let mut cursor = Cursor::new(&wrapper_bytes_bedrock); + let mut cursor = Cursor::new(&wrapper_bytes_bedrock[..]); let mut reader = deserializer::NbtReadHelperBedrock::new(&mut cursor); Nbt::read(&mut reader).unwrap(); }); diff --git a/pumpkin-nbt/src/compound.rs b/pumpkin-nbt/src/compound.rs index 67c2926d0..4d157189a 100644 --- a/pumpkin-nbt/src/compound.rs +++ b/pumpkin-nbt/src/compound.rs @@ -43,7 +43,7 @@ impl NbtCompound { } } - pub fn skip_content(reader: &mut R) -> Result<(), Error> { + pub fn skip_content<'a, R: NbtReadHelper<'a>>(reader: &mut R) -> Result<(), Error> { loop { let tag_id = match reader.get_u8() { Ok(id) => id, @@ -64,7 +64,7 @@ impl NbtCompound { Ok(()) } - pub fn deserialize_content(reader: &mut R) -> Result { + pub fn deserialize_content<'a, R: NbtReadHelper<'a>>(reader: &mut R) -> Result { let mut compound = Self::new(); loop { diff --git a/pumpkin-nbt/src/deserializer.rs b/pumpkin-nbt/src/deserializer.rs index 33c0a490c..85d25a20e 100644 --- a/pumpkin-nbt/src/deserializer.rs +++ b/pumpkin-nbt/src/deserializer.rs @@ -1,5 +1,6 @@ +use std::borrow::Cow; use std::cell::RefCell; -use std::io::{Seek, SeekFrom}; +use std::io::{Cursor, Seek, SeekFrom}; use crate::{ BYTE_ARRAY_ID, BYTE_ID, COMPOUND_ID, END_ID, Error, INT_ARRAY_ID, INT_ID, LIST_ID, @@ -25,16 +26,178 @@ pub(super) fn set_curr_visitor_seq_list_id(tag: Option) { }); } -pub trait NbtReadHelper { - type Reader: Read + Seek; +pub trait NbtDataSource<'a> { + fn read_u8(&mut self) -> Result; + fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()>; + fn seek_relative(&mut self, offset: i64) -> Result<()>; + fn read_string(&mut self, len: usize) -> Result>; + fn read_byte_array(&mut self, len: usize) -> Result>; +} + +pub struct NbtStreamReader(pub R); + +impl<'a, R: Read + Seek> NbtDataSource<'a> for NbtStreamReader { + fn read_u8(&mut self) -> Result { + let mut buf = [0u8; 1]; + self.0.read_exact(&mut buf).map_err(Error::Incomplete)?; + Ok(buf[0]) + } + + fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> { + self.0.read_exact(buf).map_err(Error::Incomplete) + } + + fn seek_relative(&mut self, offset: i64) -> Result<()> { + self.0 + .seek(SeekFrom::Current(offset)) + .map_err(Error::Incomplete)?; + Ok(()) + } + + fn read_string(&mut self, len: usize) -> Result> { + let mut buf = vec![0u8; len]; + self.0.read_exact(&mut buf).map_err(Error::Incomplete)?; + let string = cesu8::from_java_cesu8(&buf).map_err(|_| Error::Cesu8DecodingError)?; + Ok(Cow::Owned(string.into_owned())) + } + + fn read_byte_array(&mut self, len: usize) -> Result> { + let mut buf = vec![0u8; len]; + self.0.read_exact(&mut buf).map_err(Error::Incomplete)?; + let i8_buf: Vec = buf.into_iter().map(|b| b as i8).collect(); + Ok(Cow::Owned(i8_buf)) + } +} + +impl<'a> NbtDataSource<'a> for Cursor<&'a [u8]> { + fn read_u8(&mut self) -> Result { + let mut buf = [0u8; 1]; + self.read_exact(&mut buf).map_err(Error::Incomplete)?; + Ok(buf[0]) + } + + fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> { + self.read_exact(buf).map_err(Error::Incomplete) + } + + fn seek_relative(&mut self, offset: i64) -> Result<()> { + self.seek(SeekFrom::Current(offset)) + .map_err(Error::Incomplete)?; + Ok(()) + } + + fn read_string(&mut self, len: usize) -> Result> { + let pos = self.position() as usize; + let data_len = self.get_ref().len(); + if pos + len > data_len { + return Err(Error::Incomplete(std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "unexpected EOF", + ))); + } + self.set_position((pos + len) as u64); + let data = self.get_ref(); + let slice = &data[pos..pos + len]; + if let Ok(s) = std::str::from_utf8(slice) { + Ok(Cow::Borrowed(s)) + } else { + let string = cesu8::from_java_cesu8(slice).map_err(|_| Error::Cesu8DecodingError)?; + Ok(string) + } + } + + fn read_byte_array(&mut self, len: usize) -> Result> { + let pos = self.position() as usize; + let data_len = self.get_ref().len(); + if pos + len > data_len { + return Err(Error::Incomplete(std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "unexpected EOF", + ))); + } + self.set_position((pos + len) as u64); + let data = self.get_ref(); + let slice = &data[pos..pos + len]; + let i8_slice = unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::(), len) }; + Ok(Cow::Borrowed(i8_slice)) + } +} + +impl<'a, S: NbtDataSource<'a> + ?Sized> NbtDataSource<'a> for &mut S { + fn read_u8(&mut self) -> Result { + (**self).read_u8() + } + fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> { + (**self).read_bytes(buf) + } + fn seek_relative(&mut self, offset: i64) -> Result<()> { + (**self).seek_relative(offset) + } + fn read_string(&mut self, len: usize) -> Result> { + (**self).read_string(len) + } + fn read_byte_array(&mut self, len: usize) -> Result> { + (**self).read_byte_array(len) + } +} + +impl<'a> NbtDataSource<'a> for Cursor> { + fn read_u8(&mut self) -> Result { + let mut buf = [0u8; 1]; + self.read_exact(&mut buf).map_err(Error::Incomplete)?; + Ok(buf[0]) + } + + fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> { + self.read_exact(buf).map_err(Error::Incomplete) + } + + fn seek_relative(&mut self, offset: i64) -> Result<()> { + self.seek(SeekFrom::Current(offset)) + .map_err(Error::Incomplete)?; + Ok(()) + } + + fn read_string(&mut self, len: usize) -> Result> { + let pos = self.position() as usize; + let data_len = self.get_ref().len(); + if pos + len > data_len { + return Err(Error::Incomplete(std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "unexpected EOF", + ))); + } + self.set_position((pos + len) as u64); + let data = self.get_ref(); + let slice = &data[pos..pos + len]; + let string = cesu8::from_java_cesu8(slice).map_err(|_| Error::Cesu8DecodingError)?; + Ok(Cow::Owned(string.into_owned())) + } + + fn read_byte_array(&mut self, len: usize) -> Result> { + let pos = self.position() as usize; + let data_len = self.get_ref().len(); + if pos + len > data_len { + return Err(Error::Incomplete(std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "unexpected EOF", + ))); + } + self.set_position((pos + len) as u64); + let data = self.get_ref(); + let slice = &data[pos..pos + len]; + let i8_slice = unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::(), len) }; + Ok(Cow::Owned(i8_slice.to_vec())) + } +} + +pub trait NbtReadHelper<'a> { + type Reader: NbtDataSource<'a>; fn reader(&mut self) -> &mut Self::Reader; fn skip_bytes(&mut self, count: i64) -> Result<()> { - self.reader() - .seek(SeekFrom::Current(count)) - .map_err(Error::Incomplete)?; - Ok(()) + self.reader().seek_relative(count) } fn skip_u8(&mut self) -> Result<()> { self.skip_bytes(1) @@ -66,63 +229,42 @@ pub trait NbtReadHelper { fn get_i64(&mut self) -> Result; fn get_f32(&mut self) -> Result; fn get_f64(&mut self) -> Result; - fn get_string(&mut self) -> Result; + fn get_string(&mut self) -> Result>; + fn get_byte_array(&mut self, len: usize) -> Result>; } -macro_rules! define_get_number_be { - ($name:ident, $type:ty) => { - fn $name(&mut self) -> Result<$type> { - let mut buf = [0u8; std::mem::size_of::<$type>()]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(<$type>::from_be_bytes(buf)) - } - }; +pub struct NbtReadHelperJava { + reader: D, } -macro_rules! define_get_number_le { - ($name:ident, $type:ty) => { - fn $name(&mut self) -> Result<$type> { - let mut buf = [0u8; std::mem::size_of::<$type>()]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(<$type>::from_le_bytes(buf)) - } - }; -} - -pub struct NbtReadHelperJava { - reader: R, -} - -impl NbtReadHelperJava { - pub const fn new(r: R) -> Self { +impl NbtReadHelperJava { + pub const fn new(r: D) -> Self { Self { reader: r } } } -pub struct NbtReadHelperBedrock { - reader: R, +pub struct NbtReadHelperBedrock { + reader: D, } -impl NbtReadHelperBedrock { - pub const fn new(r: R) -> Self { +impl NbtReadHelperBedrock { + pub const fn new(r: D) -> Self { Self { reader: r } } } -impl NbtReadHelperJava { - define_get_number_be!(get_string_len, u16); +impl<'a, D: NbtDataSource<'a>> NbtReadHelperJava { + fn get_string_len(&mut self) -> Result { + let mut buf = [0u8; 2]; + self.reader.read_bytes(&mut buf)?; + Ok(u16::from_be_bytes(buf)) + } } -impl NbtReadHelper for NbtReadHelperJava { - type Reader = R; +impl<'a, D: NbtDataSource<'a>> NbtReadHelper<'a> for NbtReadHelperJava { + type Reader = D; - fn reader(&mut self) -> &mut R { + fn reader(&mut self) -> &mut D { &mut self.reader } @@ -131,31 +273,54 @@ impl NbtReadHelper for NbtReadHelperJava { self.skip_bytes(len) } - define_get_number_be!(get_u8, u8); - define_get_number_be!(get_i8, i8); - define_get_number_be!(get_i16, i16); - define_get_number_be!(get_i32, i32); - define_get_number_be!(get_i64, i64); - define_get_number_be!(get_f32, f32); - define_get_number_be!(get_f64, f64); + fn get_u8(&mut self) -> Result { + self.reader.read_u8() + } + fn get_i8(&mut self) -> Result { + Ok(self.reader.read_u8()? as i8) + } + fn get_i16(&mut self) -> Result { + let mut buf = [0u8; 2]; + self.reader.read_bytes(&mut buf)?; + Ok(i16::from_be_bytes(buf)) + } + fn get_i32(&mut self) -> Result { + let mut buf = [0u8; 4]; + self.reader.read_bytes(&mut buf)?; + Ok(i32::from_be_bytes(buf)) + } + fn get_i64(&mut self) -> Result { + let mut buf = [0u8; 8]; + self.reader.read_bytes(&mut buf)?; + Ok(i64::from_be_bytes(buf)) + } + fn get_f32(&mut self) -> Result { + let mut buf = [0u8; 4]; + self.reader.read_bytes(&mut buf)?; + Ok(f32::from_be_bytes(buf)) + } + fn get_f64(&mut self) -> Result { + let mut buf = [0u8; 8]; + self.reader.read_bytes(&mut buf)?; + Ok(f64::from_be_bytes(buf)) + } - fn get_string(&mut self) -> Result { + fn get_string(&mut self) -> Result> { let len = self.get_string_len()? as usize; + self.reader.read_string(len) + } - let mut buf = vec![0u8; len]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - let string = cesu8::from_java_cesu8(&buf).map_err(|_| Error::Cesu8DecodingError)?; - - Ok(string.into_owned()) + fn get_byte_array(&mut self, len: usize) -> Result> { + self.reader.read_byte_array(len) } } -impl NbtReadHelperBedrock { +impl<'a, D: NbtDataSource<'a>> NbtReadHelperBedrock { + fn get_u8(&mut self) -> Result { + self.reader.read_u8() + } + fn get_var_u32(&mut self) -> Result { - // LEB128 let mut val = 0; for i in 0..5 { let byte = self.get_u8()?; @@ -169,12 +334,10 @@ impl NbtReadHelperBedrock { fn get_var_i32(&mut self) -> Result { let val = self.get_var_u32()?; - // ZigZag Ok(((val >> 1) as i32) ^ -((val as i32) & 1)) } fn get_var_u64(&mut self) -> Result { - // LEB128 let mut val = 0; for i in 0..10 { let byte = self.get_u8()?; @@ -188,7 +351,6 @@ impl NbtReadHelperBedrock { fn get_var_i64(&mut self) -> Result { let val = self.get_var_u64()?; - // ZigZag Ok(((val >> 1) as i64) ^ -((val as i64) & 1)) } @@ -197,67 +359,64 @@ impl NbtReadHelperBedrock { } } -impl NbtReadHelper for NbtReadHelperBedrock { - type Reader = R; +impl<'a, D: NbtDataSource<'a>> NbtReadHelper<'a> for NbtReadHelperBedrock { + type Reader = D; - fn reader(&mut self) -> &mut Self::Reader { + fn reader(&mut self) -> &mut D { &mut self.reader } - fn skip_i32(&mut self) -> Result<()> { - for _ in 0..5 { - if self.get_u8()? & 0x80 == 0 { - return Ok(()); - } - } - Err(Error::VarIntTooLarge) - } - fn skip_i64(&mut self) -> Result<()> { - for _ in 0..10 { - if self.get_u8()? & 0x80 == 0 { - return Ok(()); - } - } - Err(Error::VarLongTooLarge) - } fn skip_string(&mut self) -> Result<()> { let len = self.get_string_len()? as i64; self.skip_bytes(len) } - define_get_number_le!(get_u8, u8); - define_get_number_le!(get_i8, i8); - define_get_number_le!(get_i16, i16); + fn get_u8(&mut self) -> Result { + self.reader.read_u8() + } + fn get_i8(&mut self) -> Result { + Ok(self.reader.read_u8()? as i8) + } + fn get_i16(&mut self) -> Result { + let mut buf = [0u8; 2]; + self.reader.read_bytes(&mut buf)?; + Ok(i16::from_le_bytes(buf)) + } fn get_i32(&mut self) -> Result { self.get_var_i32() } fn get_i64(&mut self) -> Result { self.get_var_i64() } - define_get_number_le!(get_f32, f32); - define_get_number_le!(get_f64, f64); + fn get_f32(&mut self) -> Result { + let mut buf = [0u8; 4]; + self.reader.read_bytes(&mut buf)?; + Ok(f32::from_le_bytes(buf)) + } + fn get_f64(&mut self) -> Result { + let mut buf = [0u8; 8]; + self.reader.read_bytes(&mut buf)?; + Ok(f64::from_le_bytes(buf)) + } - fn get_string(&mut self) -> Result { + fn get_string(&mut self) -> Result> { let len = self.get_string_len()? as usize; + self.reader.read_string(len) + } - let mut buf = vec![0u8; len]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - String::from_utf8(buf).map_err(|_| Error::Utf8DecodingError) + fn get_byte_array(&mut self, len: usize) -> Result> { + self.reader.read_byte_array(len) } } -pub struct Deserializer { +pub struct Deserializer { input: R, tag_to_deserialize_stack: Option, - // Yes, this breaks with recursion. Just an attempt at a sanity check in_list: bool, is_named: bool, } -impl Deserializer { +impl Deserializer { pub const fn new(input: R, is_named: bool) -> Self { Self { input, @@ -270,28 +429,46 @@ impl Deserializer { /// Deserializes struct using Serde Deserializer from normal NBT pub fn from_bytes<'a, T: Deserialize<'a>>(r: impl Read + Seek) -> Result { - let mut deserializer = Deserializer::new(NbtReadHelperJava::new(r), true); + let mut deserializer = Deserializer::new(NbtReadHelperJava::new(NbtStreamReader(r)), true); T::deserialize(&mut deserializer) } /// Deserializes struct using Serde Deserializer from network NBT pub fn from_bytes_unnamed<'a, T: Deserialize<'a>>(r: impl Read + Seek) -> Result { - let mut deserializer = Deserializer::new(NbtReadHelperJava::new(r), false); + let mut deserializer = Deserializer::new(NbtReadHelperJava::new(NbtStreamReader(r)), false); T::deserialize(&mut deserializer) } /// Deserializes struct using Serde Deserializer from Bedrock network NBT pub fn from_bytes_bedrock<'a, T: Deserialize<'a>>(r: impl Read + Seek) -> Result { - let mut deserializer = Deserializer::new(NbtReadHelperBedrock::new(r), true); + let mut deserializer = Deserializer::new(NbtReadHelperBedrock::new(NbtStreamReader(r)), true); T::deserialize(&mut deserializer) } -impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { +/// Deserializes struct using Serde Deserializer from a normal NBT slice (zero-allocation) +pub fn from_slice<'a, T: Deserialize<'a>>(slice: &'a [u8]) -> Result { + let mut deserializer = Deserializer::new(NbtReadHelperJava::new(Cursor::new(slice)), true); + T::deserialize(&mut deserializer) +} + +/// Deserializes struct using Serde Deserializer from a network NBT slice (zero-allocation) +pub fn from_slice_unnamed<'a, T: Deserialize<'a>>(slice: &'a [u8]) -> Result { + let mut deserializer = Deserializer::new(NbtReadHelperJava::new(Cursor::new(slice)), false); + T::deserialize(&mut deserializer) +} + +/// Deserializes struct using Serde Deserializer from a Bedrock network NBT slice (zero-allocation) +pub fn from_slice_bedrock<'a, T: Deserialize<'a>>(slice: &'a [u8]) -> Result { + let mut deserializer = Deserializer::new(NbtReadHelperBedrock::new(Cursor::new(slice)), true); + T::deserialize(&mut deserializer) +} + +impl<'de, R: NbtReadHelper<'de>> de::Deserializer<'de> for &mut Deserializer { type Error = Error; forward_to_deserialize_any! { - i8 i16 i32 i64 f32 f64 char str string unit unit_struct seq tuple tuple_struct - bytes newtype_struct byte_buf + i8 i16 i32 i64 f32 f64 char unit unit_struct seq tuple tuple_struct + newtype_struct byte_buf } fn deserialize_ignored_any>(self, visitor: V) -> Result { @@ -334,8 +511,6 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { return Err(Error::LargeLength(remaining_values)); } - //TODO this is a bit hacky but I couldn't think of a better way - // This flag gets auto cleared in visit_seq set_curr_visitor_seq_list_id(Some(list_type)); let result = visitor.visit_seq(ListAccess { de: self, @@ -353,7 +528,7 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { NbtTag::Long(value) => visitor.visit_i64::(value)?, NbtTag::Float(value) => visitor.visit_f32::(value)?, NbtTag::Double(value) => visitor.visit_f64::(value)?, - NbtTag::String(value) => visitor.visit_string::(value.into())?, + NbtTag::String(value) => visitor.visit_string::(value.into_string())?, _ => return Err(Error::SerdeError("Unreachable state reached".to_string())), }; Ok(result) @@ -378,13 +553,11 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { } fn deserialize_u32>(self, visitor: V) -> Result { - // ZigZag might make this a problem for Bedrock... let value = self.input.get_i32()?; visitor.visit_i32::(value) } fn deserialize_u64>(self, visitor: V) -> Result { - // ZigZag might make this a problem for Bedrock... let value = self.input.get_i64()?; visitor.visit_i64::(value) } @@ -399,18 +572,49 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { visitor.visit_bool(false) } + fn deserialize_str>(self, visitor: V) -> Result { + match self.input.get_string()? { + Cow::Borrowed(s) => visitor.visit_borrowed_str(s), + Cow::Owned(s) => visitor.visit_string(s), + } + } + + fn deserialize_string>(self, visitor: V) -> Result { + self.deserialize_str(visitor) + } + + fn deserialize_bytes>(self, visitor: V) -> Result { + let tag_id = self.tag_to_deserialize_stack.unwrap_or(BYTE_ARRAY_ID); + if tag_id == BYTE_ARRAY_ID { + let len = self.input.get_i32()?; + if len < 0 { + return Err(Error::NegativeLength(len)); + } + let slice = self.input.get_byte_array(len as usize)?; + let u8_slice: &'de [u8] = + unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::(), slice.len()) }; + match slice { + Cow::Borrowed(_) => visitor.visit_borrowed_bytes(u8_slice), + Cow::Owned(_) => visitor.visit_bytes(u8_slice), + } + } else { + self.deserialize_any(visitor) + } + } + fn deserialize_enum>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result { - let variant = self.input.get_string()?; - visitor.visit_enum(variant.into_deserializer()) + match self.input.get_string()? { + Cow::Borrowed(s) => visitor.visit_enum(s.into_deserializer()), + Cow::Owned(s) => visitor.visit_enum(s.into_deserializer()), + } } fn deserialize_option>(self, visitor: V) -> Result { - // None is not encoded, so no need for it visitor.visit_some(self) } @@ -446,8 +650,7 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { } fn deserialize_identifier>(self, visitor: V) -> Result { - let str = self.input.get_string()?; - visitor.visit_string(str) + self.deserialize_str(visitor) } fn is_human_readable(&self) -> bool { @@ -455,11 +658,11 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for &mut Deserializer { } } -struct CompoundAccess<'a, R: NbtReadHelper> { +struct CompoundAccess<'a, R> { de: &'a mut Deserializer, } -impl<'de, R: NbtReadHelper> MapAccess<'de> for CompoundAccess<'_, R> { +impl<'de, R: NbtReadHelper<'de>> MapAccess<'de> for CompoundAccess<'_, R> { type Error = Error; fn next_key_seed>(&mut self, seed: K) -> Result> { @@ -478,16 +681,18 @@ impl<'de, R: NbtReadHelper> MapAccess<'de> for CompoundAccess<'_, R> { } } -struct MapKey<'a, R: NbtReadHelper> { +struct MapKey<'a, R> { de: &'a mut Deserializer, } -impl<'de, R: NbtReadHelper> de::Deserializer<'de> for MapKey<'_, R> { +impl<'de, R: NbtReadHelper<'de>> de::Deserializer<'de> for MapKey<'_, R> { type Error = Error; fn deserialize_any>(self, visitor: V) -> Result { - let key = self.de.input.get_string()?; - visitor.visit_string(key) + match self.de.input.get_string()? { + Cow::Borrowed(s) => visitor.visit_borrowed_str(s), + Cow::Owned(s) => visitor.visit_string(s), + } } forward_to_deserialize_any! { @@ -496,13 +701,13 @@ impl<'de, R: NbtReadHelper> de::Deserializer<'de> for MapKey<'_, R> { } } -struct ListAccess<'a, R: NbtReadHelper> { +struct ListAccess<'a, R> { de: &'a mut Deserializer, remaining_values: usize, list_type: u8, } -impl<'de, R: NbtReadHelper> SeqAccess<'de> for ListAccess<'_, R> { +impl<'de, R: NbtReadHelper<'de>> SeqAccess<'de> for ListAccess<'_, R> { type Error = Error; fn size_hint(&self) -> Option { diff --git a/pumpkin-nbt/src/lib.rs b/pumpkin-nbt/src/lib.rs index 53c01c283..9cd87e218 100644 --- a/pumpkin-nbt/src/lib.rs +++ b/pumpkin-nbt/src/lib.rs @@ -19,7 +19,10 @@ pub mod serializer; pub mod tag; pub use compound::NbtCompound; -pub use deserializer::{from_bytes, from_bytes_unnamed}; +pub use deserializer::{ + from_bytes, from_bytes_bedrock, from_bytes_unnamed, from_slice, from_slice_bedrock, + from_slice_unnamed, +}; pub use serializer::{to_bytes, to_bytes_named, to_bytes_unnamed}; // This NBT crate is inspired from CrabNBT @@ -93,7 +96,7 @@ impl Nbt { } } - pub fn read(reader: &mut R) -> Result { + pub fn read<'a, R: NbtReadHelper<'a>>(reader: &mut R) -> Result { let tag_type_id = reader.get_u8()?; if tag_type_id != COMPOUND_ID { @@ -101,13 +104,13 @@ impl Nbt { } Ok(Self { - name: reader.get_string()?, + name: reader.get_string()?.into_owned(), root_tag: NbtCompound::deserialize_content(reader)?, }) } /// Reads an NBT tag that doesn't contain the name of the root `Compound`. - pub fn read_unnamed(reader: &mut R) -> Result { + pub fn read_unnamed<'a, R: NbtReadHelper<'a>>(reader: &mut R) -> Result { let tag_type_id = reader.get_u8()?; if tag_type_id != COMPOUND_ID { @@ -256,6 +259,31 @@ mod test { string: String, } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct BorrowedTest<'a> { + byte: i8, + string: &'a str, + } + + #[test] + fn zero_alloc_from_slice() { + let test = Test { + byte: 123, + short: 1342, + int: 4313, + long: 34, + float: 1.00, + string: "Zero alloc NBT".to_string(), + }; + + let mut bytes = Vec::new(); + to_bytes_unnamed(&test, &mut bytes).unwrap(); + let borrowed: BorrowedTest = crate::from_slice_unnamed(&bytes).unwrap(); + + assert_eq!(borrowed.byte, 123); + assert_eq!(borrowed.string, "Zero alloc NBT"); + } + #[test] fn simple_ser_de_unnamed() { let test = Test { diff --git a/pumpkin-nbt/src/tag.rs b/pumpkin-nbt/src/tag.rs index cf34900ac..4b309e2cd 100644 --- a/pumpkin-nbt/src/tag.rs +++ b/pumpkin-nbt/src/tag.rs @@ -175,12 +175,12 @@ impl NbtTag { Ok(()) } - pub fn deserialize(reader: &mut R) -> Result { + pub fn deserialize<'a, R: NbtReadHelper<'a>>(reader: &mut R) -> Result { let tag_id = reader.get_u8()?; Self::deserialize_data(reader, tag_id) } - pub fn skip_data(reader: &mut R, tag_id: u8) -> Result<(), Error> { + pub fn skip_data<'a, R: NbtReadHelper<'a>>(reader: &mut R, tag_id: u8) -> Result<(), Error> { match tag_id { END_ID => Ok(()), BYTE_ID => reader.skip_i8(), @@ -239,7 +239,10 @@ impl NbtTag { } } - pub fn deserialize_data(reader: &mut R, tag_id: u8) -> Result { + pub fn deserialize_data<'a, R: NbtReadHelper<'a>>( + reader: &mut R, + tag_id: u8, + ) -> Result { match tag_id { END_ID => Ok(Self::End), BYTE_ID => { @@ -283,7 +286,7 @@ impl NbtTag { } Ok(Self::ByteArray(byte_array.into())) } - STRING_ID => Ok(Self::String(reader.get_string()?.into())), + STRING_ID => Ok(Self::String(reader.get_string()?.into_owned().into())), LIST_ID => { let tag_type_id = reader.get_u8()?; let len = reader.get_i32()?; diff --git a/pumpkin-protocol/src/bedrock/server/command_request.rs b/pumpkin-protocol/src/bedrock/server/command_request.rs index e4d272318..c411363ab 100644 --- a/pumpkin-protocol/src/bedrock/server/command_request.rs +++ b/pumpkin-protocol/src/bedrock/server/command_request.rs @@ -1,19 +1,60 @@ use pumpkin_macros::packet; +use std::borrow::Cow; use uuid::Uuid; -use crate::serial::PacketRead; +use crate::serial::{PacketRead, PacketReadSlice, read_str_slice}; -#[derive(Debug, PacketRead)] +#[derive(Debug)] #[packet(77)] -pub struct SCommandRequest { - pub command: String, - - // Command Origin - pub command_type: String, +pub struct SCommandRequest<'a> { + pub command: Cow<'a, str>, + pub command_type: Cow<'a, str>, pub command_uuid: Uuid, - pub request_id: String, + pub request_id: Cow<'a, str>, pub player_actor_unique_id: i64, - pub is_internal_source: bool, - pub version: String, + pub version: Cow<'a, str>, +} + +impl<'a> PacketReadSlice<'a> for SCommandRequest<'a> { + fn read_slice(buf: &mut &'a [u8]) -> Result { + let command = Cow::Borrowed(read_str_slice(buf)?); + let command_type = Cow::Borrowed(read_str_slice(buf)?); + let command_uuid = Uuid::read_slice(buf)?; + let request_id = Cow::Borrowed(read_str_slice(buf)?); + let player_actor_unique_id = i64::read_slice(buf)?; + let is_internal_source = bool::read_slice(buf)?; + let version = Cow::Borrowed(read_str_slice(buf)?); + Ok(Self { + command, + command_type, + command_uuid, + request_id, + player_actor_unique_id, + is_internal_source, + version, + }) + } +} + +impl PacketRead for SCommandRequest<'static> { + fn read(reader: &mut R) -> Result { + let command = Cow::Owned(String::read(reader)?); + let command_type = Cow::Owned(String::read(reader)?); + let command_uuid = Uuid::read(reader)?; + let request_id = Cow::Owned(String::read(reader)?); + let player_actor_unique_id = i64::read(reader)?; + let is_internal_source = bool::read(reader)?; + let version = Cow::Owned(String::read(reader)?); + + Ok(Self { + command, + command_type, + command_uuid, + request_id, + player_actor_unique_id, + is_internal_source, + version, + }) + } } diff --git a/pumpkin-protocol/src/bedrock/server/emote.rs b/pumpkin-protocol/src/bedrock/server/emote.rs index e1899fc8a..b98599dac 100644 --- a/pumpkin-protocol/src/bedrock/server/emote.rs +++ b/pumpkin-protocol/src/bedrock/server/emote.rs @@ -1,17 +1,62 @@ use crate::codec::var_ulong::VarULong; -use crate::serial::{PacketRead, PacketWrite}; +use crate::serial::{PacketRead, PacketReadSlice, PacketWrite, read_str_slice}; use pumpkin_macros::packet; +use std::borrow::Cow; +use std::io::{Error, Write}; pub const EMOTE_FLAG_SERVER_SIDE: u8 = 1 << 0; pub const EMOTE_FLAG_MUTE_CHAT: u8 = 1 << 1; -#[derive(PacketRead, PacketWrite, Debug)] +#[derive(Debug)] #[packet(138)] -pub struct SEmote { +pub struct SEmote<'a> { pub runtime_entity_id: VarULong, - pub emote_id: String, + pub emote_id: Cow<'a, str>, pub emote_length: u32, - pub xuid: String, - pub platform_id: String, + pub xuid: Cow<'a, str>, + pub platform_id: Cow<'a, str>, pub flags: u8, } + +impl<'a> PacketReadSlice<'a> for SEmote<'a> { + fn read_slice(buf: &mut &'a [u8]) -> Result { + let runtime_entity_id = VarULong::read_slice(buf)?; + let emote_id = Cow::Borrowed(read_str_slice(buf)?); + let emote_length = u32::read_slice(buf)?; + let xuid = Cow::Borrowed(read_str_slice(buf)?); + let platform_id = Cow::Borrowed(read_str_slice(buf)?); + let flags = u8::read_slice(buf)?; + Ok(Self { + runtime_entity_id, + emote_id, + emote_length, + xuid, + platform_id, + flags, + }) + } +} + +impl PacketRead for SEmote<'static> { + fn read(reader: &mut R) -> Result { + Ok(Self { + runtime_entity_id: VarULong::read(reader)?, + emote_id: Cow::Owned(String::read(reader)?), + emote_length: u32::read(reader)?, + xuid: Cow::Owned(String::read(reader)?), + platform_id: Cow::Owned(String::read(reader)?), + flags: u8::read(reader)?, + }) + } +} + +impl PacketWrite for SEmote<'_> { + fn write(&self, writer: &mut W) -> Result<(), Error> { + self.runtime_entity_id.write(writer)?; + self.emote_id.as_ref().write(writer)?; + self.emote_length.write(writer)?; + self.xuid.as_ref().write(writer)?; + self.platform_id.as_ref().write(writer)?; + self.flags.write(writer) + } +} diff --git a/pumpkin-protocol/src/bedrock/server/modal_form_response.rs b/pumpkin-protocol/src/bedrock/server/modal_form_response.rs index ffa15e3da..0848581f2 100644 --- a/pumpkin-protocol/src/bedrock/server/modal_form_response.rs +++ b/pumpkin-protocol/src/bedrock/server/modal_form_response.rs @@ -1,18 +1,30 @@ use crate::codec::var_int::VarInt; -use crate::serial::PacketRead; +use crate::serial::{PacketRead, PacketReadSlice, read_str_slice}; use pumpkin_macros::packet; +use std::borrow::Cow; use std::io::{Error, Read}; +#[derive(Debug)] #[packet(101)] -pub struct SModalFormResponse { +pub struct SModalFormResponse<'a> { pub form_id: VarInt, - pub form_data: Option, + pub form_data: Option>, } -impl PacketRead for SModalFormResponse { +impl<'a> PacketReadSlice<'a> for SModalFormResponse<'a> { + fn read_slice(buf: &mut &'a [u8]) -> Result { + let form_id = VarInt::read_slice(buf)?; + let form_data = bool::read_slice(buf)? + .then(|| read_str_slice(buf).map(Cow::Borrowed)) + .transpose()?; + Ok(Self { form_id, form_data }) + } +} + +impl PacketRead for SModalFormResponse<'static> { fn read(reader: &mut R) -> Result { let form_id = VarInt::read(reader)?; - let form_data = Option::::read(reader)?; + let form_data = Option::::read(reader)?.map(Cow::Owned); Ok(Self { form_id, form_data }) } } diff --git a/pumpkin-protocol/src/bedrock/server/text.rs b/pumpkin-protocol/src/bedrock/server/text.rs index 302668dcb..cebbbbdf4 100644 --- a/pumpkin-protocol/src/bedrock/server/text.rs +++ b/pumpkin-protocol/src/bedrock/server/text.rs @@ -1,52 +1,70 @@ use crate::{ codec::var_uint::VarUInt, - serial::{PacketRead, PacketWrite}, + serial::{PacketRead, PacketReadSlice, PacketWrite, read_str_slice}, }; use pumpkin_macros::packet; +use std::borrow::Cow; use std::io::{Error, ErrorKind, Read, Write}; #[derive(Debug)] #[packet(9)] -pub struct SText { +pub struct SText<'a> { pub needs_translation: bool, pub r#type: TextPacketType, - pub source_name: String, - pub message: String, - pub parameters: Vec, - pub xuid: String, - pub platform_chat_id: String, - pub filtered_message: Option, + pub source_name: Cow<'a, str>, + pub message: Cow<'a, str>, + pub parameters: Vec>, + pub xuid: Cow<'a, str>, + pub platform_chat_id: Cow<'a, str>, + pub filtered_message: Option>, } -impl SText { +impl SText<'_> { + const fn get_category(&self) -> u8 { + match self.r#type { + TextPacketType::Raw + | TextPacketType::Tip + | TextPacketType::System + | TextPacketType::JsonWhisper + | TextPacketType::JsonAnnouncement + | TextPacketType::Json => 0, + + TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => 1, + + TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => 2, + } + } +} + +impl SText<'static> { #[must_use] pub fn new(message: String, source_name: String) -> Self { Self { needs_translation: false, r#type: TextPacketType::Chat, - source_name, - message: if message.is_empty() { + source_name: Cow::Owned(source_name), + message: Cow::Owned(if message.is_empty() { " ".to_string() } else { message - }, + }), parameters: Vec::new(), - xuid: String::new(), - platform_chat_id: String::new(), + xuid: Cow::Borrowed(""), + platform_chat_id: Cow::Borrowed(""), filtered_message: None, } } #[must_use] - pub const fn translation(message: String, parameters: Vec) -> Self { + pub fn translation(message: String, parameters: Vec) -> Self { Self { needs_translation: true, r#type: TextPacketType::Translation, - source_name: String::new(), - message, - parameters, - xuid: String::new(), - platform_chat_id: String::new(), + source_name: Cow::Borrowed(""), + message: Cow::Owned(message), + parameters: parameters.into_iter().map(Cow::Owned).collect(), + xuid: Cow::Borrowed(""), + platform_chat_id: Cow::Borrowed(""), filtered_message: None, } } @@ -56,15 +74,15 @@ impl SText { Self { needs_translation: false, r#type: TextPacketType::System, - source_name: String::new(), - message: if message.is_empty() { + source_name: Cow::Borrowed(""), + message: Cow::Owned(if message.is_empty() { " ".to_string() } else { message - }, + }), parameters: Vec::new(), - xuid: String::new(), - platform_chat_id: String::new(), + xuid: Cow::Borrowed(""), + platform_chat_id: Cow::Borrowed(""), filtered_message: None, } } @@ -74,37 +92,72 @@ impl SText { Self { needs_translation: false, r#type: TextPacketType::Json, - source_name: String::new(), - message, + source_name: Cow::Borrowed(""), + message: Cow::Owned(message), parameters: Vec::new(), - xuid: String::new(), - platform_chat_id: String::new(), + xuid: Cow::Borrowed(""), + platform_chat_id: Cow::Borrowed(""), filtered_message: None, } } - - const fn get_category(&self) -> u8 { - match self.r#type { - TextPacketType::Raw - | TextPacketType::Tip - | TextPacketType::System - | TextPacketType::JsonWhisper - | TextPacketType::JsonAnnouncement - | TextPacketType::Json => 0, // CATEGORY_MESSAGE_ONLY - - TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => 1, // CATEGORY_AUTHORED_MESSAGE - - TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => 2, // CATEGORY_MESSAGE_WITH_PARAMETERS - } - } } -impl PacketRead for SText { +impl<'a> PacketReadSlice<'a> for SText<'a> { + fn read_slice(buf: &mut &'a [u8]) -> Result { + let needs_translation = bool::read_slice(buf)?; + let _category = u8::read_slice(buf)?; + let r#type = TextPacketType::read_slice(buf)?; + + let mut source_name = ""; + let message; + let mut parameters: Vec> = Vec::new(); + + match r#type { + TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => { + source_name = read_str_slice(buf)?; + message = read_str_slice(buf)?; + } + TextPacketType::Raw + | TextPacketType::Tip + | TextPacketType::System + | TextPacketType::JsonWhisper + | TextPacketType::Json + | TextPacketType::JsonAnnouncement => { + message = read_str_slice(buf)?; + } + TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => { + message = read_str_slice(buf)?; + let count = VarUInt::read_slice(buf)?.0 as usize; + for _ in 0..count { + parameters.push(Cow::Borrowed(read_str_slice(buf)?)); + } + } + } + + let xuid = read_str_slice(buf)?; + let platform_chat_id = read_str_slice(buf)?; + + let filtered_message = bool::read_slice(buf)? + .then(|| read_str_slice(buf).map(Cow::Borrowed)) + .transpose()?; + + Ok(Self { + needs_translation, + r#type, + source_name: Cow::Borrowed(source_name), + message: Cow::Borrowed(message), + parameters, + xuid: Cow::Borrowed(xuid), + platform_chat_id: Cow::Borrowed(platform_chat_id), + filtered_message, + }) + } +} + +impl PacketRead for SText<'static> { fn read(reader: &mut R) -> Result { let needs_translation = bool::read(reader)?; - let _category = u8::read(reader)?; - let r#type = TextPacketType::read(reader)?; let mut source_name = String::new(); @@ -129,7 +182,7 @@ impl PacketRead for SText { message = String::read(reader)?; let count = VarUInt::read(reader)?.0 as usize; for _ in 0..count { - parameters.push(String::read(reader)?); + parameters.push(Cow::Owned(String::read(reader)?)); } } } @@ -138,23 +191,23 @@ impl PacketRead for SText { let platform_chat_id = String::read(reader)?; let filtered_message = bool::read(reader)? - .then(|| String::read(reader)) + .then(|| String::read(reader).map(Cow::Owned)) .transpose()?; Ok(Self { needs_translation, r#type, - source_name, - message, + source_name: Cow::Owned(source_name), + message: Cow::Owned(message), parameters, - xuid, - platform_chat_id, + xuid: Cow::Owned(xuid), + platform_chat_id: Cow::Owned(platform_chat_id), filtered_message, }) } } -impl PacketWrite for SText { +impl PacketWrite for SText<'_> { fn write(&self, writer: &mut W) -> Result<(), Error> { self.needs_translation.write(writer)?; @@ -165,8 +218,8 @@ impl PacketWrite for SText { match self.r#type { TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => { - self.source_name.write(writer)?; - self.message.write(writer)?; + self.source_name.as_ref().write(writer)?; + self.message.as_ref().write(writer)?; } TextPacketType::Raw | TextPacketType::Tip @@ -174,23 +227,23 @@ impl PacketWrite for SText { | TextPacketType::JsonWhisper | TextPacketType::Json | TextPacketType::JsonAnnouncement => { - self.message.write(writer)?; + self.message.as_ref().write(writer)?; } TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => { - self.message.write(writer)?; + self.message.as_ref().write(writer)?; VarUInt(self.parameters.len() as u32).write(writer)?; for param in &self.parameters { - param.write(writer)?; + param.as_ref().write(writer)?; } } } - self.xuid.write(writer)?; - self.platform_chat_id.write(writer)?; + self.xuid.as_ref().write(writer)?; + self.platform_chat_id.as_ref().write(writer)?; if let Some(msg) = &self.filtered_message { true.write(writer)?; - msg.write(writer)?; + msg.as_ref().write(writer)?; } else { false.write(writer)?; } @@ -241,3 +294,23 @@ impl PacketRead for TextPacketType { } } } + +impl<'a> PacketReadSlice<'a> for TextPacketType { + fn read_slice(buf: &mut &'a [u8]) -> Result { + match u8::read_slice(buf)? { + 0 => Ok(Self::Raw), + 1 => Ok(Self::Chat), + 2 => Ok(Self::Translation), + 3 => Ok(Self::Popup), + 4 => Ok(Self::JukeboxPopup), + 5 => Ok(Self::Tip), + 6 => Ok(Self::System), + 7 => Ok(Self::Whisper), + 8 => Ok(Self::Announcement), + 9 => Ok(Self::JsonWhisper), + 10 => Ok(Self::Json), + 11 => Ok(Self::JsonAnnouncement), + _ => Err(Error::new(ErrorKind::InvalidData, "Unknown Text Type")), + } + } +} diff --git a/pumpkin-protocol/src/codec/item_stack_seralizer.rs b/pumpkin-protocol/src/codec/item_stack_seralizer.rs index 9957ab846..67102aa4c 100644 --- a/pumpkin-protocol/src/codec/item_stack_seralizer.rs +++ b/pumpkin-protocol/src/codec/item_stack_seralizer.rs @@ -106,16 +106,30 @@ fn read_length_prefixed_component( ) -> Result<(DataComponent, Box), ReadingError> { let id = read_component_id(read)?; let byte_len = read.get_var_int()?.0; - let byte_len = byte_len + let byte_len: usize = byte_len .try_into() .map_err(|_| ReadingError::Message("Negative component data length".into()))?; - let component_data = read.read_boxed_slice(byte_len)?; - let component_impl = if id == DataComponent::CustomName { - decode_custom_name(component_data.as_ref())? + let component_impl = if byte_len <= 256 { + let mut stack_buf = [0u8; 256]; + let slice = &mut stack_buf[..byte_len]; + read.read_bytes_to_buf(slice)?; + + if id == DataComponent::CustomName { + decode_custom_name(slice)? + } else { + let mut cursor = Cursor::new(slice); + deserialize(id, &mut cursor)? + } } else { - let mut cursor = Cursor::new(component_data); - deserialize(id, &mut cursor)? + let mut component_data = vec![0u8; byte_len]; + read.read_bytes_to_buf(&mut component_data)?; + if id == DataComponent::CustomName { + decode_custom_name(component_data.as_ref())? + } else { + let mut cursor = Cursor::new(component_data); + deserialize(id, &mut cursor)? + } }; Ok((id, component_impl)) @@ -297,13 +311,11 @@ impl ItemComponentHash { pub fn read(read: &mut impl NetworkReadExt) -> Result { const MAX_COMPONENTS: i32 = 256; - let mut added = Vec::new(); - let mut removed = Vec::new(); - let added_length = read.get_var_int()?; if added_length.0 < 0 || added_length.0 > MAX_COMPONENTS { return Err(ReadingError::Message("added_length out of bounds".into())); } + let mut added = Vec::with_capacity(added_length.0 as usize); for _ in 0..added_length.0 { let component_id = read.get_var_int()?; let component_value = read.get_i32()?; @@ -314,6 +326,7 @@ impl ItemComponentHash { if removed_length.0 < 0 || removed_length.0 > MAX_COMPONENTS { return Err(ReadingError::Message("removed_length out of bounds".into())); } + let mut removed = Vec::with_capacity(removed_length.0 as usize); for _ in 0..removed_length.0 { let component_id = read.get_var_int()?; removed.push(component_id); diff --git a/pumpkin-protocol/src/java/client/play/login.rs b/pumpkin-protocol/src/java/client/play/login.rs index a350875de..db4a55392 100644 --- a/pumpkin-protocol/src/java/client/play/login.rs +++ b/pumpkin-protocol/src/java/client/play/login.rs @@ -16,12 +16,12 @@ use crate::{ /// initializes the player's world view, dimension settings, and local game /// rules. Once received, the client begins rendering the world. #[java_packet(PLAY_LOGIN)] -pub struct CLogin { +pub struct CLogin<'a> { /// The unique ID assigned to the player for the current session. pub entity_id: i32, pub is_hardcore: bool, /// A list of all dimensions present on the server (e.g., overworld, nether, end). - pub dimension_names: Vec, + pub dimension_names: &'a [ResourceLocation], pub max_players: VarInt, /// The number of chunks the client will render in each direction. pub view_distance: VarInt, @@ -38,14 +38,14 @@ pub struct CLogin { pub enforce_secure_chat: bool, } -impl CLogin { +impl<'a> CLogin<'a> { #[expect(clippy::too_many_arguments)] #[expect(clippy::fn_params_excessive_bools)] #[must_use] pub const fn new( entity_id: i32, is_hardcore: bool, - dimension_names: Vec, + dimension_names: &'a [ResourceLocation], max_players: VarInt, view_distance: VarInt, simulated_distance: VarInt, @@ -73,7 +73,7 @@ impl CLogin { } } -impl ClientPacket for CLogin { +impl ClientPacket for CLogin<'_> { fn write_packet_data( &self, mut write: impl std::io::Write, @@ -81,7 +81,7 @@ impl ClientPacket for CLogin { ) -> Result<(), WritingError> { write.write_i32_be(self.entity_id)?; write.write_bool(self.is_hardcore)?; - write.write_list(&self.dimension_names, |write, dim| write.write_string(dim))?; + write.write_list(self.dimension_names, |write, dim| write.write_string(dim))?; write.write_var_int(&self.max_players)?; write.write_var_int(&self.view_distance)?; write.write_var_int(&self.simulated_distance)?; diff --git a/pumpkin-protocol/src/java/client/play/player_position.rs b/pumpkin-protocol/src/java/client/play/player_position.rs index 45116bc78..d5d9c33c9 100644 --- a/pumpkin-protocol/src/java/client/play/player_position.rs +++ b/pumpkin-protocol/src/java/client/play/player_position.rs @@ -84,9 +84,9 @@ impl ClientPacket for CPlayerPosition { } } -impl ServerPacket for CPlayerPosition { +impl<'a> ServerPacket<'a> for CPlayerPosition { fn read( - mut read: impl std::io::Read, + read: &mut &'a [u8], _version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/packet_decoder.rs b/pumpkin-protocol/src/java/packet_decoder.rs index cc4325147..ae4330de8 100644 --- a/pumpkin-protocol/src/java/packet_decoder.rs +++ b/pumpkin-protocol/src/java/packet_decoder.rs @@ -191,7 +191,10 @@ impl TCPNetworkDecoder { } } - let payload = self.payload_scratch.split().freeze(); + let payload = self + .payload_scratch + .split_to(self.payload_scratch.len()) + .freeze(); Ok(RawPacket { id: packet_id, @@ -456,4 +459,40 @@ mod tests { assert_eq!(raw_packet.payload.as_ref(), payload); Ok(()) } + + /// Test decoding multiple packets sequentially to verify capacity is retained for zero allocation + #[tokio::test] + async fn decode_multiple_packets_zero_allocation() -> Result<(), Box> { + let packet1 = build_packet(1, b"Hello", false, None, None)?; + let packet2 = build_packet(2, b"World", false, None, None)?; + + let mut stream = Vec::new(); + stream.extend_from_slice(&packet1); + stream.extend_from_slice(&packet2); + + let mut decoder = TCPNetworkDecoder::new(stream.as_slice()); + + let p1 = decoder.get_raw_packet().await?; + assert_eq!(p1.id, 1); + assert_eq!(p1.payload.as_ref(), b"Hello"); + drop(p1); + + let cap_after_p1 = decoder.payload_scratch.capacity(); + assert!( + cap_after_p1 > 0, + "Capacity should be allocated after first read" + ); + + let p2 = decoder.get_raw_packet().await?; + assert_eq!(p2.id, 2); + assert_eq!(p2.payload.as_ref(), b"World"); + drop(p2); + + let cap_after_p2 = decoder.payload_scratch.capacity(); + assert_eq!( + cap_after_p2, cap_after_p1, + "Buffer capacity should be retained and reused without new heap allocations" + ); + Ok(()) + } } diff --git a/pumpkin-protocol/src/java/packet_encoder.rs b/pumpkin-protocol/src/java/packet_encoder.rs index dea5041ca..a8ea3140c 100644 --- a/pumpkin-protocol/src/java/packet_encoder.rs +++ b/pumpkin-protocol/src/java/packet_encoder.rs @@ -204,9 +204,6 @@ impl TCPNetworkEncoder { /// NOTE: This method does not flush. Call [`Self::flush`] to flush buffered data. #[allow(clippy::too_many_lines)] pub async fn write_packet(&mut self, packet_data: Bytes) -> Result<(), PacketEncodeError> { - // We need to know the length of the compressed buffer and serde is not async :( - // We need to write to a buffer here 😔 - let data_len = packet_data.len(); if data_len > MAX_PACKET_DATA_SIZE { return Err(PacketEncodeError::TooLong(data_len)); @@ -218,14 +215,13 @@ impl TCPNetworkEncoder { )) })?; - if let Some((compression_threshold, compression_level)) = self.compression { - if data_len >= compression_threshold { - // Pushed before data: - // Length of (Data Length) + length of compressed (Packet ID + Data) - // Length of uncompressed (Packet ID + Data) + let mut header_buf = [0u8; 10]; + let mut header_cursor = std::io::Cursor::new(&mut header_buf[..]); - // TODO: We need the compressed length at the beginning of the packet so we need to write to - // buf here :( Is there a magic way to find a compressed length? + let payload_to_write: &[u8] = if let Some((compression_threshold, compression_level)) = + self.compression + { + if data_len >= compression_threshold { self.compress_packet_data(packet_data.as_ref(), compression_level)?; debug_assert!(!self.compression_scratch.is_empty()); @@ -245,24 +241,14 @@ impl TCPNetworkEncoder { } full_packet_len_var_int - .encode_async(self.writer.as_mut().unwrap()) - .await + .encode(&mut header_cursor) .map_err(|err| PacketEncodeError::Message(err.to_string()))?; data_len_var_int - .encode_async(self.writer.as_mut().unwrap()) - .await + .encode(&mut header_cursor) .map_err(|err| PacketEncodeError::Message(err.to_string()))?; - self.writer - .as_mut() - .unwrap() - .write_all(&self.compression_scratch) - .await - .map_err(|err| PacketEncodeError::Message(err.to_string()))?; - } else { - // Pushed before data: - // Length of (Data Length) + length of compressed (Packet ID + Data) - // 0 to indicate uncompressed + self.compression_scratch.as_slice() + } else { let data_len_var_int: VarInt = 0.into(); let full_packet_len_var_int: VarInt = (data_len_var_int.written_size() + data_len) .try_into() @@ -279,24 +265,15 @@ impl TCPNetworkEncoder { } full_packet_len_var_int - .encode_async(self.writer.as_mut().unwrap()) - .await + .encode(&mut header_cursor) .map_err(|err| PacketEncodeError::Message(err.to_string()))?; data_len_var_int - .encode_async(self.writer.as_mut().unwrap()) - .await - .map_err(|err| PacketEncodeError::Message(err.to_string()))?; - self.writer - .as_mut() - .unwrap() - .write_all(&packet_data) - .await + .encode(&mut header_cursor) .map_err(|err| PacketEncodeError::Message(err.to_string()))?; + + packet_data.as_ref() } } else { - // Pushed before data: - // Length of Packet ID + Data - let full_packet_len_var_int: VarInt = data_len_var_int; let complete_serialization_length = @@ -306,16 +283,27 @@ impl TCPNetworkEncoder { } full_packet_len_var_int - .encode_async(self.writer.as_mut().unwrap()) - .await + .encode(&mut header_cursor) .map_err(|err| PacketEncodeError::Message(err.to_string()))?; - self.writer - .as_mut() - .unwrap() - .write_all(&packet_data) - .await - .map_err(|err| PacketEncodeError::Message(err.to_string()))?; - } + + packet_data.as_ref() + }; + + let header_len = header_cursor.position() as usize; + let header_bytes = &header_buf[..header_len]; + let writer = self + .writer + .as_mut() + .ok_or_else(|| PacketEncodeError::Message("Writer missing".into()))?; + + writer + .write_all(header_bytes) + .await + .map_err(|err| PacketEncodeError::Message(err.to_string()))?; + writer + .write_all(payload_to_write) + .await + .map_err(|err| PacketEncodeError::Message(err.to_string()))?; Ok(()) } @@ -323,7 +311,7 @@ impl TCPNetworkEncoder { pub async fn flush(&mut self) -> Result<(), PacketEncodeError> { self.writer .as_mut() - .unwrap() + .ok_or_else(|| PacketEncodeError::Message("Writer missing".into()))? .flush() .await .map_err(|err| PacketEncodeError::Message(err.to_string())) diff --git a/pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs b/pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs index bcb2ecc5b..e821bc5fb 100644 --- a/pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs +++ b/pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs @@ -3,15 +3,17 @@ use pumpkin_macros::java_packet; use crate::{ServerPacket, ser::ReadingError}; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; /// This packet signals to the server that the client is ready to transition /// from the `Configuration` state to the `Play` state. #[java_packet(CONFIG_FINISH_CONFIGURATION)] pub struct SAcknowledgeFinishConfig; -impl ServerPacket for SAcknowledgeFinishConfig { - fn read(_bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SAcknowledgeFinishConfig { + fn read( + _bytebuf: &mut &'a [u8], + _version: &JavaMinecraftVersion, + ) -> Result { Ok(Self) } } diff --git a/pumpkin-protocol/src/java/server/config/client_information.rs b/pumpkin-protocol/src/java/server/config/client_information.rs index 624941e88..8a3fe48b5 100644 --- a/pumpkin-protocol/src/java/server/config/client_information.rs +++ b/pumpkin-protocol/src/java/server/config/client_information.rs @@ -5,16 +5,15 @@ use crate::VarInt; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; /// Sent by the client to inform the server about its local settings #[java_packet(CONFIG_CLIENT_INFORMATION)] -pub struct SClientInformationConfig { +pub struct SClientInformationConfig<'a> { /// The language code used by the client (e.g., "`en_us`") - pub locale: String, + pub locale: &'a str, /// The maximum number of chunks the client renders pub view_distance: i8, /// Visibility of chat messages (0: Enabled, 1: Commands Only, 2: Hidden) @@ -31,10 +30,10 @@ pub struct SClientInformationConfig { pub server_listing: bool, } -impl ServerPacket for SClientInformationConfig { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SClientInformationConfig<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - locale: bytebuf.get_str()?.into_string(), + locale: bytebuf.get_str_borrowed()?, view_distance: bytebuf.get_i8()?, chat_mode: bytebuf.get_var_int()?, chat_colors: bytebuf.get_bool()?, diff --git a/pumpkin-protocol/src/java/server/config/cookie_response.rs b/pumpkin-protocol/src/java/server/config/cookie_response.rs index 83a8ebf28..d597f8afc 100644 --- a/pumpkin-protocol/src/java/server/config/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/config/cookie_response.rs @@ -1,10 +1,11 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; +use crate::{ + ReadingError, ServerPacket, + ser::{NetworkReadExt, NetworkReadSliceExt}, +}; /// The maximum allowed size for a cookie payload (5 KiB). const MAX_COOKIE_LENGTH: usize = 5120; @@ -14,19 +15,18 @@ const MAX_COOKIE_LENGTH: usize = 5120; /// Cookies allow servers to store small amounts of data on the client side, /// which can be retrieved later (e.g., for session tracking or preferences) #[java_packet(CONFIG_COOKIE_RESPONSE)] -pub struct SConfigCookieResponse { +pub struct SConfigCookieResponse<'a> { /// The unique identifier for the cookie being returned - pub key: Box, + pub key: &'a str, /// Indicates whether a payload is attached to this response pub has_payload: bool, /// The actual data stored in the cookie. Limited to 5120 bytes - pub payload: Option>, + pub payload: Option<&'a [u8]>, } -impl ServerPacket for SConfigCookieResponse { - fn read(read: impl Read, _version: &JavaMinecraftVersion) -> Result { - let mut read = read; - let key = read.get_str()?; +impl<'a> ServerPacket<'a> for SConfigCookieResponse<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { + let key = read.get_str_borrowed()?; let has_payload = read.get_bool()?; if !has_payload { @@ -42,7 +42,7 @@ impl ServerPacket for SConfigCookieResponse { return Err(ReadingError::TooLarge("SConfigCookieResponse".to_string())); } - let payload = read.read_boxed_slice(payload_length)?; + let payload = read.read_slice_borrowed(payload_length)?; Ok(Self { key, has_payload, diff --git a/pumpkin-protocol/src/java/server/config/custom_click_action.rs b/pumpkin-protocol/src/java/server/config/custom_click_action.rs index b44d6f95d..73b78d833 100644 --- a/pumpkin-protocol/src/java/server/config/custom_click_action.rs +++ b/pumpkin-protocol/src/java/server/config/custom_click_action.rs @@ -1,25 +1,22 @@ -use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_CLICK_ACTION; -use pumpkin_macros::java_packet; -use pumpkin_util::resource_location::ResourceLocation; - use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; +use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_CLICK_ACTION; +use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(CONFIG_CUSTOM_CLICK_ACTION)] -pub struct SCustomClickAction { - pub action_id: ResourceLocation, - pub payload: Option>, +pub struct SCustomClickAction<'a> { + pub action_id: &'a str, + pub payload: Option<&'a [u8]>, } -impl ServerPacket for SCustomClickAction { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SCustomClickAction<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - action_id: bytebuf.get_str()?.into_string(), - payload: bytebuf.get_option(|v| v.read_remaining_to_boxed_slice(32767))?, + action_id: bytebuf.get_str_borrowed()?, + payload: bytebuf.get_option(|v| v.read_remaining_slice_borrowed(32767))?, }) } } diff --git a/pumpkin-protocol/src/java/server/config/keep_alive.rs b/pumpkin-protocol/src/java/server/config/keep_alive.rs index fae25aa70..b9d7af794 100644 --- a/pumpkin-protocol/src/java/server/config/keep_alive.rs +++ b/pumpkin-protocol/src/java/server/config/keep_alive.rs @@ -6,15 +6,14 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(CONFIG_KEEP_ALIVE)] pub struct SKeepAlive { pub keep_alive_id: i64, } -impl ServerPacket for SKeepAlive { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SKeepAlive { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { keep_alive_id: bytebuf.get_i64_be()?, }) diff --git a/pumpkin-protocol/src/java/server/config/known_packs.rs b/pumpkin-protocol/src/java/server/config/known_packs.rs index 6e2756e29..8da89ffa7 100644 --- a/pumpkin-protocol/src/java/server/config/known_packs.rs +++ b/pumpkin-protocol/src/java/server/config/known_packs.rs @@ -8,7 +8,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(CONFIG_SELECT_KNOWN_PACKS)] pub struct SKnownPacks { @@ -16,8 +15,8 @@ pub struct SKnownPacks { // known_packs: &'a [KnownPack] } -impl ServerPacket for SKnownPacks { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SKnownPacks { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { known_pack_count: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/config/plugin_message.rs b/pumpkin-protocol/src/java/server/config/plugin_message.rs index 3f8038efd..fa2c0cc35 100644 --- a/pumpkin-protocol/src/java/server/config/plugin_message.rs +++ b/pumpkin-protocol/src/java/server/config/plugin_message.rs @@ -1,10 +1,8 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; +use crate::{ReadingError, ServerPacket, ser::NetworkReadSliceExt}; /// The maximum allowed size for a plugin message payload (1 MiB). const MAX_PAYLOAD_SIZE: usize = 1_048_576; @@ -14,19 +12,19 @@ const MAX_PAYLOAD_SIZE: usize = 1_048_576; /// This allows mods, plugins, or proxy /// software to send proprietary data over the standard Minecraft protocol. #[java_packet(CONFIG_CUSTOM_PAYLOAD)] -pub struct SPluginMessage { +pub struct SPluginMessage<'a> { /// The name of the channel used to distinguish different types of messages. /// Example: `minecraft:brand` or `velocity:main`. - pub channel: Box, + pub channel: &'a str, /// The payload sent by the client. - pub data: Box<[u8]>, + pub data: &'a [u8], } -impl ServerPacket for SPluginMessage { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPluginMessage<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - channel: read.get_str()?, - data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?, + channel: read.get_str_borrowed()?, + data: read.read_remaining_slice_borrowed(MAX_PAYLOAD_SIZE)?, }) } } diff --git a/pumpkin-protocol/src/java/server/config/resource_pack_response.rs b/pumpkin-protocol/src/java/server/config/resource_pack_response.rs index 0017ba185..68f54025e 100644 --- a/pumpkin-protocol/src/java/server/config/resource_pack_response.rs +++ b/pumpkin-protocol/src/java/server/config/resource_pack_response.rs @@ -6,7 +6,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -34,8 +33,8 @@ pub struct SConfigResourcePack { pub result: VarInt, } -impl ServerPacket for SConfigResourcePack { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SConfigResourcePack { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { uuid: bytebuf.get_uuid()?, result: bytebuf.get_var_int()?, diff --git a/pumpkin-protocol/src/java/server/handshake/mod.rs b/pumpkin-protocol/src/java/server/handshake/mod.rs index 65adcf601..f3f407b08 100644 --- a/pumpkin-protocol/src/java/server/handshake/mod.rs +++ b/pumpkin-protocol/src/java/server/handshake/mod.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use crate::{ ClientPacket, ConnectionState, ReadingError, ServerPacket, VarInt, ser::NetworkReadExt, ser::NetworkWriteExt, @@ -24,8 +22,8 @@ pub struct SHandShake { pub next_state: ConnectionState, } -impl ServerPacket for SHandShake { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SHandShake { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { protocol_version: read.get_var_int()?, server_address: read.get_str_bounded(255)?, diff --git a/pumpkin-protocol/src/java/server/login/cookie_response.rs b/pumpkin-protocol/src/java/server/login/cookie_response.rs index 3f5c6ebd7..e37c3888f 100644 --- a/pumpkin-protocol/src/java/server/login/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/login/cookie_response.rs @@ -1,26 +1,25 @@ use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; #[java_packet(LOGIN_COOKIE_RESPONSE)] /// Response to a `CCookieRequest` (login) from the server. /// The Notchian server only accepts responses of up to 5 kiB in size. -pub struct SLoginCookieResponse { - pub key: Box, - pub payload: Option>, // 5120, +pub struct SLoginCookieResponse<'a> { + pub key: &'a str, + pub payload: Option<&'a [u8]>, // 5120, } const MAX_COOKIE_LENGTH: usize = 5120; -impl ServerPacket for SLoginCookieResponse { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { - let key = read.get_str()?; +impl<'a> ServerPacket<'a> for SLoginCookieResponse<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { + let key = read.get_str_borrowed()?; let has_payload = read.get_bool()?; if !has_payload { @@ -33,7 +32,7 @@ impl ServerPacket for SLoginCookieResponse { return Err(ReadingError::TooLarge("SLoginCookieResponse".to_string())); } - let payload = read.read_boxed_slice(length)?; + let payload = read.read_slice_borrowed(length)?; Ok(Self { key, diff --git a/pumpkin-protocol/src/java/server/login/encryption_response.rs b/pumpkin-protocol/src/java/server/login/encryption_response.rs index 2546e63f6..f7765b900 100644 --- a/pumpkin-protocol/src/java/server/login/encryption_response.rs +++ b/pumpkin-protocol/src/java/server/login/encryption_response.rs @@ -1,26 +1,36 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::LOGIN_KEY; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; +#[derive(Clone, Debug, PartialEq, Eq)] #[java_packet(LOGIN_KEY)] pub struct SEncryptionResponse { pub shared_secret: Box<[u8]>, pub verify_token: Box<[u8]>, } -impl ServerPacket for SEncryptionResponse { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { - let shared_secret_length = read.get_var_int()?.0 as usize; - let shared_secret = read.read_boxed_slice(shared_secret_length)?; - let verify_token_length = read.get_var_int()?.0 as usize; - let verify_token = read.read_boxed_slice(verify_token_length)?; +impl<'a> ServerPacket<'a> for SEncryptionResponse { + fn read( + mut read: &mut &'a [u8], + _version: &JavaMinecraftVersion, + ) -> Result { + let shared_secret = read_encryption_buffer(&mut read)?; + let verify_token = read_encryption_buffer(&mut read)?; Ok(Self { shared_secret, verify_token, }) } } + +fn read_encryption_buffer(read: &mut impl NetworkReadExt) -> Result, ReadingError> { + let length = read.get_var_int()?.0 as usize; + if length > 256 { + return Err(ReadingError::Message("Encryption payload too large".into())); + } + let mut data = vec![0u8; length]; + read.read_bytes_to_buf(&mut data)?; + Ok(data.into_boxed_slice()) +} diff --git a/pumpkin-protocol/src/java/server/login/login_response.rs b/pumpkin-protocol/src/java/server/login/login_response.rs index 5a8dab410..418c0d9a3 100644 --- a/pumpkin-protocol/src/java/server/login/login_response.rs +++ b/pumpkin-protocol/src/java/server/login/login_response.rs @@ -3,14 +3,16 @@ use pumpkin_macros::java_packet; use crate::{ServerPacket, ser::ReadingError}; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; /// Acknowledgement to the `CLoginSuccess` packet sent by the server. #[java_packet(LOGIN_LOGIN_ACKNOWLEDGED)] pub struct SLoginAcknowledged; -impl ServerPacket for SLoginAcknowledged { - fn read(_bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SLoginAcknowledged { + fn read( + _bytebuf: &mut &'a [u8], + _version: &JavaMinecraftVersion, + ) -> Result { Ok(Self) } } diff --git a/pumpkin-protocol/src/java/server/login/login_start.rs b/pumpkin-protocol/src/java/server/login/login_start.rs index 7660d6b0f..63645633a 100644 --- a/pumpkin-protocol/src/java/server/login/login_start.rs +++ b/pumpkin-protocol/src/java/server/login/login_start.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::LOGIN_HELLO; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; @@ -15,8 +13,8 @@ pub struct SLoginStart { pub uuid: uuid::Uuid, } -impl ServerPacket for SLoginStart { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SLoginStart { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { name: read.get_str_bounded(16)?, uuid: read.get_uuid()?, diff --git a/pumpkin-protocol/src/java/server/login/plugin_response.rs b/pumpkin-protocol/src/java/server/login/plugin_response.rs index ba8dfee88..7307dc6be 100644 --- a/pumpkin-protocol/src/java/server/login/plugin_response.rs +++ b/pumpkin-protocol/src/java/server/login/plugin_response.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use crate::{ReadingError, ServerPacket, VarInt, ser::NetworkReadExt}; use pumpkin_data::packet::serverbound::LOGIN_CUSTOM_QUERY_ANSWER; use pumpkin_macros::java_packet; @@ -13,11 +11,11 @@ pub struct SLoginPluginResponse { pub data: Option>, } -impl ServerPacket for SLoginPluginResponse { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SLoginPluginResponse { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { message_id: read.get_var_int()?, - data: read.get_option(|v| v.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE))?, + data: read.get_option(|v| crate::ser::read_remaining_bytes(v, MAX_PAYLOAD_SIZE))?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/attack.rs b/pumpkin-protocol/src/java/server/play/attack.rs index 4f1e2b3f8..e801212b0 100644 --- a/pumpkin-protocol/src/java/server/play/attack.rs +++ b/pumpkin-protocol/src/java/server/play/attack.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_ATTACK; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::codec::var_int::VarInt; @@ -14,9 +13,9 @@ pub struct SAttack { pub entity_id: VarInt, } -impl ServerPacket for SAttack { +impl<'a> ServerPacket<'a> for SAttack { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/bundle_item_selected.rs b/pumpkin-protocol/src/java/server/play/bundle_item_selected.rs index b62ce0f04..b87f1b0b3 100644 --- a/pumpkin-protocol/src/java/server/play/bundle_item_selected.rs +++ b/pumpkin-protocol/src/java/server/play/bundle_item_selected.rs @@ -8,7 +8,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_BUNDLE_ITEM_SELECTED)] pub struct SBundleItemSelected { @@ -16,8 +15,8 @@ pub struct SBundleItemSelected { pub selected_item_index: VarInt, } -impl ServerPacket for SBundleItemSelected { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SBundleItemSelected { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { slot_id: bytebuf.get_var_int()?, selected_item_index: bytebuf.get_var_int()?, diff --git a/pumpkin-protocol/src/java/server/play/change_game_mode.rs b/pumpkin-protocol/src/java/server/play/change_game_mode.rs index a02705ca9..9852bcff9 100644 --- a/pumpkin-protocol/src/java/server/play/change_game_mode.rs +++ b/pumpkin-protocol/src/java/server/play/change_game_mode.rs @@ -6,15 +6,14 @@ use pumpkin_data::packet::serverbound::PLAY_CHANGE_GAME_MODE; use pumpkin_macros::java_packet; use pumpkin_util::GameMode; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_CHANGE_GAME_MODE)] pub struct SChangeGameMode { pub game_mode: GameMode, } -impl ServerPacket for SChangeGameMode { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SChangeGameMode { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { game_mode: GameMode::try_from(bytebuf.get_u8()? as i8) .map_err(|()| crate::ser::ReadingError::Message("Invalid game mode".into()))?, diff --git a/pumpkin-protocol/src/java/server/play/chat_command.rs b/pumpkin-protocol/src/java/server/play/chat_command.rs index 80adad496..850b1a681 100644 --- a/pumpkin-protocol/src/java/server/play/chat_command.rs +++ b/pumpkin-protocol/src/java/server/play/chat_command.rs @@ -3,20 +3,19 @@ use pumpkin_macros::java_packet; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadSliceExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_CHAT_COMMAND)] -pub struct SChatCommand { - pub command: String, +pub struct SChatCommand<'a> { + pub command: &'a str, } -impl ServerPacket for SChatCommand { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SChatCommand<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - command: bytebuf.get_str()?.into_string(), + command: bytebuf.get_str_borrowed()?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/chat_message.rs b/pumpkin-protocol/src/java/server/play/chat_message.rs index 17ff1b66d..8ce6e9cfa 100644 --- a/pumpkin-protocol/src/java/server/play/chat_message.rs +++ b/pumpkin-protocol/src/java/server/play/chat_message.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_CHAT; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; @@ -8,46 +6,46 @@ use crate::{ ClientPacket, ServerPacket, codec::var_int::VarInt, ser::NetworkWriteExt, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; #[java_packet(PLAY_CHAT)] -pub struct SChatMessage { - pub message: Box, +pub struct SChatMessage<'a> { + pub message: &'a str, pub timestamp: i64, pub salt: i64, - pub signature: Option>, + pub signature: Option<&'a [u8]>, pub message_count: VarInt, - pub acknowledged: Box<[u8]>, // Bitset fixed 20 bits - pub checksum: u8, // 1.21.5 "fingerprint" checksum + pub acknowledged: &'a [u8], // Bitset fixed 20 bits + pub checksum: u8, // 1.21.5 "fingerprint" checksum } -impl ServerPacket for SChatMessage { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SChatMessage<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - message: read.get_str_bounded(256)?, + message: read.get_str_bounded_borrowed(256)?, timestamp: read.get_i64_be()?, salt: read.get_i64_be()?, - signature: read.get_option(|v| v.read_boxed_slice(256))?, + signature: read.get_option(|v| v.read_slice_borrowed(256))?, message_count: read.get_var_int()?, - acknowledged: read.get_fixed_bitset(20)?, + acknowledged: read.read_slice_borrowed(3)?, checksum: read.get_u8()?, }) } } -impl ClientPacket for SChatMessage { +impl ClientPacket for SChatMessage<'_> { fn write_packet_data( &self, mut write: impl std::io::Write, _version: &JavaMinecraftVersion, ) -> Result<(), crate::ser::WritingError> { - write.write_string(&self.message)?; + write.write_string(self.message)?; write.write_i64_be(self.timestamp)?; write.write_i64_be(self.salt)?; write.write_option(&self.signature, |p, v| p.write_slice(v))?; write.write_var_int(&self.message_count)?; - write.write_fixed_bitset(20, self.acknowledged.clone())?; + write.write_slice(self.acknowledged)?; write.write_u8(self.checksum)?; Ok(()) diff --git a/pumpkin-protocol/src/java/server/play/chunk_batch.rs b/pumpkin-protocol/src/java/server/play/chunk_batch.rs index a2d2baa90..ab67b1879 100644 --- a/pumpkin-protocol/src/java/server/play/chunk_batch.rs +++ b/pumpkin-protocol/src/java/server/play/chunk_batch.rs @@ -5,15 +5,14 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_CHUNK_BATCH_RECEIVED; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_CHUNK_BATCH_RECEIVED)] pub struct SChunkBatch { pub chunks_per_tick: f32, } -impl ServerPacket for SChunkBatch { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SChunkBatch { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { chunks_per_tick: bytebuf.get_f32_be()?, }) diff --git a/pumpkin-protocol/src/java/server/play/click_container.rs b/pumpkin-protocol/src/java/server/play/click_container.rs index fd996bdba..8846d3cae 100644 --- a/pumpkin-protocol/src/java/server/play/click_container.rs +++ b/pumpkin-protocol/src/java/server/play/click_container.rs @@ -22,8 +22,11 @@ pub struct SClickSlot { pub carried_item: OptionalItemStackHash, } -impl ServerPacket for SClickSlot { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SClickSlot { + fn read( + mut bytebuf: &mut &'a [u8], + _version: &JavaMinecraftVersion, + ) -> Result { let sync_id = bytebuf.get_var_int()?; let revision = bytebuf.get_var_int()?; let slot = bytebuf.get_i16_be()?; @@ -31,6 +34,11 @@ impl ServerPacket for SClickSlot { let mode = SlotActionType::read(&mut bytebuf)?; let length_of_array = bytebuf.get_var_int()?; + if length_of_array.0 < 0 || length_of_array.0 > 256 { + return Err(ReadingError::Message( + "Changed slots length out of bounds".into(), + )); + } let mut array_of_changed_slots = Vec::with_capacity(length_of_array.0 as usize); for _ in 0..length_of_array.0 { array_of_changed_slots.push(( diff --git a/pumpkin-protocol/src/java/server/play/client_command.rs b/pumpkin-protocol/src/java/server/play/client_command.rs index 9d3380c8c..8c62e03bf 100644 --- a/pumpkin-protocol/src/java/server/play/client_command.rs +++ b/pumpkin-protocol/src/java/server/play/client_command.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_CLIENT_COMMAND; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -14,8 +13,8 @@ pub struct SClientCommand { pub action_id: VarInt, } -impl ServerPacket for SClientCommand { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SClientCommand { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { action_id: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/client_information.rs b/pumpkin-protocol/src/java/server/play/client_information.rs index c651486f0..c91bbf137 100644 --- a/pumpkin-protocol/src/java/server/play/client_information.rs +++ b/pumpkin-protocol/src/java/server/play/client_information.rs @@ -1,17 +1,16 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_CLIENT_INFORMATION; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; #[java_packet(PLAY_CLIENT_INFORMATION)] -pub struct SClientInformationPlay { - pub locale: String, // 16 +pub struct SClientInformationPlay<'a> { + pub locale: &'a str, // 16 pub view_distance: i8, pub chat_mode: VarInt, // VarInt pub chat_colors: bool, @@ -21,10 +20,10 @@ pub struct SClientInformationPlay { pub server_listing: bool, } -impl ServerPacket for SClientInformationPlay { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SClientInformationPlay<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - locale: bytebuf.get_str()?.to_string(), + locale: bytebuf.get_str_borrowed()?, view_distance: bytebuf.get_i8()?, chat_mode: bytebuf.get_var_int()?, chat_colors: bytebuf.get_bool()?, diff --git a/pumpkin-protocol/src/java/server/play/close_container.rs b/pumpkin-protocol/src/java/server/play/close_container.rs index b47dca883..e1d8e3a81 100644 --- a/pumpkin-protocol/src/java/server/play/close_container.rs +++ b/pumpkin-protocol/src/java/server/play/close_container.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_CONTAINER_CLOSE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -14,8 +13,8 @@ pub struct SCloseContainer { pub window_id: VarInt, } -impl ServerPacket for SCloseContainer { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SCloseContainer { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { window_id: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/command_suggestion.rs b/pumpkin-protocol/src/java/server/play/command_suggestion.rs index 55b7e4275..44a9a317c 100644 --- a/pumpkin-protocol/src/java/server/play/command_suggestion.rs +++ b/pumpkin-protocol/src/java/server/play/command_suggestion.rs @@ -5,22 +5,21 @@ use crate::VarInt; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_COMMAND_SUGGESTION)] -pub struct SCommandSuggestion { +pub struct SCommandSuggestion<'a> { pub id: VarInt, - pub command: String, + pub command: &'a str, } -impl ServerPacket for SCommandSuggestion { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SCommandSuggestion<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { id: bytebuf.get_var_int()?, - command: bytebuf.get_str()?.into_string(), + command: bytebuf.get_str_borrowed()?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/confirm_teleport.rs b/pumpkin-protocol/src/java/server/play/confirm_teleport.rs index 5bed271bc..fd74d8e75 100644 --- a/pumpkin-protocol/src/java/server/play/confirm_teleport.rs +++ b/pumpkin-protocol/src/java/server/play/confirm_teleport.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_ACCEPT_TELEPORTATION; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -14,8 +13,8 @@ pub struct SConfirmTeleport { pub teleport_id: VarInt, } -impl ServerPacket for SConfirmTeleport { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SConfirmTeleport { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { teleport_id: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/container_button_click.rs b/pumpkin-protocol/src/java/server/play/container_button_click.rs index 9504438c1..c1ceac1b8 100644 --- a/pumpkin-protocol/src/java/server/play/container_button_click.rs +++ b/pumpkin-protocol/src/java/server/play/container_button_click.rs @@ -7,7 +7,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[derive(Debug)] #[java_packet(PLAY_CONTAINER_BUTTON_CLICK)] @@ -16,8 +15,8 @@ pub struct SContainerButtonClick { pub button_id: VarInt, } -impl ServerPacket for SContainerButtonClick { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SContainerButtonClick { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { window_id: bytebuf.get_var_int()?, button_id: bytebuf.get_var_int()?, diff --git a/pumpkin-protocol/src/java/server/play/cookie_response.rs b/pumpkin-protocol/src/java/server/play/cookie_response.rs index f9ad1bd12..27aca3ccd 100644 --- a/pumpkin-protocol/src/java/server/play/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/play/cookie_response.rs @@ -1,27 +1,25 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; #[java_packet(PLAY_COOKIE_RESPONSE)] /// Response to a `CCookieRequest` (play) from the server. /// The Notchian (vanilla) server only accepts responses of up to 5 KiB in size. -pub struct SCookieResponse { - pub key: Box, - pub payload: Option>, // 5120, +pub struct SCookieResponse<'a> { + pub key: &'a str, + pub payload: Option<&'a [u8]>, // 5120, } const MAX_COOKIE_LENGTH: usize = 5120; -impl ServerPacket for SCookieResponse { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { - let key = read.get_str()?; +impl<'a> ServerPacket<'a> for SCookieResponse<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { + let key = read.get_str_borrowed()?; let has_payload = read.get_bool()?; if !has_payload { @@ -33,7 +31,7 @@ impl ServerPacket for SCookieResponse { return Err(ReadingError::TooLarge("SCookieResponse".to_string())); } - let payload = read.read_boxed_slice(payload_length)?; + let payload = read.read_slice_borrowed(payload_length)?; Ok(Self { key, diff --git a/pumpkin-protocol/src/java/server/play/custom_click_action.rs b/pumpkin-protocol/src/java/server/play/custom_click_action.rs index 2e7dc1490..d61955e59 100644 --- a/pumpkin-protocol/src/java/server/play/custom_click_action.rs +++ b/pumpkin-protocol/src/java/server/play/custom_click_action.rs @@ -1,24 +1,22 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_CUSTOM_CLICK_ACTION; use pumpkin_macros::java_packet; -use pumpkin_util::resource_location::ResourceLocation; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_CUSTOM_CLICK_ACTION)] -pub struct SCustomClickAction { - pub action_id: ResourceLocation, - pub payload: Option>, +pub struct SCustomClickAction<'a> { + pub action_id: &'a str, + pub payload: Option<&'a [u8]>, } -impl ServerPacket for SCustomClickAction { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SCustomClickAction<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - action_id: bytebuf.get_str()?.to_string(), - payload: bytebuf.get_option(|b| b.read_remaining_to_boxed_slice(32767))?, + action_id: bytebuf.get_str_borrowed()?, + payload: bytebuf.get_option(|b| b.read_remaining_slice_borrowed(32767))?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/custom_payload.rs b/pumpkin-protocol/src/java/server/play/custom_payload.rs index 7995267f9..d63e6cd4e 100644 --- a/pumpkin-protocol/src/java/server/play/custom_payload.rs +++ b/pumpkin-protocol/src/java/server/play/custom_payload.rs @@ -1,10 +1,8 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_CUSTOM_PAYLOAD; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; +use crate::{ReadingError, ServerPacket, ser::NetworkReadSliceExt}; /// The maximum allowed size for a play custom payload (32 KiB). const MAX_PAYLOAD_SIZE: usize = 32_767; @@ -14,19 +12,19 @@ const MAX_PAYLOAD_SIZE: usize = 32_767; /// This allows mods, plugins, or proxy software to send proprietary data over the standard /// Minecraft protocol. #[java_packet(PLAY_CUSTOM_PAYLOAD)] -pub struct SCustomPayload { +pub struct SCustomPayload<'a> { /// The name of the channel used to distinguish different types of messages. /// Example: `minecraft:brand` or `voicechat:request_secret`. - pub channel: Box, + pub channel: &'a str, /// The payload sent by the client. - pub data: Box<[u8]>, + pub data: &'a [u8], } -impl ServerPacket for SCustomPayload { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SCustomPayload<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - channel: read.get_str()?, - data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?, + channel: read.get_str_borrowed()?, + data: read.read_remaining_slice_borrowed(MAX_PAYLOAD_SIZE)?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/interact.rs b/pumpkin-protocol/src/java/server/play/interact.rs index 83512291e..d8043d037 100644 --- a/pumpkin-protocol/src/java/server/play/interact.rs +++ b/pumpkin-protocol/src/java/server/play/interact.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_INTERACT; use pumpkin_macros::java_packet; use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion}; @@ -20,8 +18,8 @@ pub struct SInteract { } // Great job Mojang ;D -impl ServerPacket for SInteract { - fn read(mut read: impl Read, version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SInteract { + fn read(mut read: &mut &'a [u8], version: &JavaMinecraftVersion) -> Result { // 26.1+ removes the 'type' field and uses doubles for location if version >= &JavaMinecraftVersion::V_26_1 { let entity_id = read.get_var_int()?; diff --git a/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs b/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs index 0ff8aff9a..9476b32f3 100644 --- a/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs +++ b/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs @@ -6,7 +6,6 @@ use pumpkin_data::packet::serverbound::PLAY_JIGSAW_GENERATE; use pumpkin_macros::java_packet; use pumpkin_util::math::position::BlockPos; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::codec::var_int::VarInt; @@ -17,9 +16,9 @@ pub struct SJigsawGenerate { pub keep_jigsaws: bool, } -impl ServerPacket for SJigsawGenerate { +impl<'a> ServerPacket<'a> for SJigsawGenerate { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/keep_alive.rs b/pumpkin-protocol/src/java/server/play/keep_alive.rs index 3680758cc..4a366afd9 100644 --- a/pumpkin-protocol/src/java/server/play/keep_alive.rs +++ b/pumpkin-protocol/src/java/server/play/keep_alive.rs @@ -6,15 +6,14 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_KEEP_ALIVE)] pub struct SKeepAlive { pub keep_alive_id: i64, } -impl ServerPacket for SKeepAlive { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SKeepAlive { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { keep_alive_id: bytebuf.get_i64_be()?, }) diff --git a/pumpkin-protocol/src/java/server/play/move_vehicle.rs b/pumpkin-protocol/src/java/server/play/move_vehicle.rs index 531036f36..5e6fc6c7b 100644 --- a/pumpkin-protocol/src/java/server/play/move_vehicle.rs +++ b/pumpkin-protocol/src/java/server/play/move_vehicle.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_MOVE_VEHICLE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_MOVE_VEHICLE)] pub struct SMoveVehicle { @@ -16,9 +15,9 @@ pub struct SMoveVehicle { pub pitch: f32, } -impl ServerPacket for SMoveVehicle { +impl<'a> ServerPacket<'a> for SMoveVehicle { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/paddle_boat.rs b/pumpkin-protocol/src/java/server/play/paddle_boat.rs index d03361d6b..53ea3f2b6 100644 --- a/pumpkin-protocol/src/java/server/play/paddle_boat.rs +++ b/pumpkin-protocol/src/java/server/play/paddle_boat.rs @@ -6,7 +6,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PADDLE_BOAT)] pub struct SPaddleBoat { @@ -14,8 +13,8 @@ pub struct SPaddleBoat { pub right_paddle: bool, } -impl ServerPacket for SPaddleBoat { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPaddleBoat { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { left_paddle: bytebuf.get_bool()?, right_paddle: bytebuf.get_bool()?, diff --git a/pumpkin-protocol/src/java/server/play/pick_item.rs b/pumpkin-protocol/src/java/server/play/pick_item.rs index fd82988de..ed9d4417f 100644 --- a/pumpkin-protocol/src/java/server/play/pick_item.rs +++ b/pumpkin-protocol/src/java/server/play/pick_item.rs @@ -8,7 +8,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PICK_ITEM_FROM_BLOCK)] pub struct SPickItemFromBlock { @@ -16,8 +15,8 @@ pub struct SPickItemFromBlock { pub include_data: bool, } -impl ServerPacket for SPickItemFromBlock { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPickItemFromBlock { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { pos: BlockPos::from_i64(bytebuf.get_i64_be()?), include_data: bytebuf.get_bool()?, @@ -31,8 +30,8 @@ pub struct SPickItemFromEntity { pub include_data: bool, } -impl ServerPacket for SPickItemFromEntity { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPickItemFromEntity { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { id: bytebuf.get_var_int()?, include_data: bytebuf.get_bool()?, diff --git a/pumpkin-protocol/src/java/server/play/ping_request.rs b/pumpkin-protocol/src/java/server/play/ping_request.rs index e30616c95..2bb16afe1 100644 --- a/pumpkin-protocol/src/java/server/play/ping_request.rs +++ b/pumpkin-protocol/src/java/server/play/ping_request.rs @@ -6,15 +6,14 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PING_REQUEST)] pub struct SPlayPingRequest { pub payload: i64, } -impl ServerPacket for SPlayPingRequest { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayPingRequest { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { payload: bytebuf.get_i64_be()?, }) diff --git a/pumpkin-protocol/src/java/server/play/place_recipe.rs b/pumpkin-protocol/src/java/server/play/place_recipe.rs index c41e2f774..a82c110aa 100644 --- a/pumpkin-protocol/src/java/server/play/place_recipe.rs +++ b/pumpkin-protocol/src/java/server/play/place_recipe.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_PLACE_RECIPE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -16,8 +15,8 @@ pub struct SPlaceRecipe { pub use_max_items: bool, } -impl ServerPacket for SPlaceRecipe { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlaceRecipe { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { container_id: bytebuf.get_i8()?, recipe_display_id: bytebuf.get_var_int()?, diff --git a/pumpkin-protocol/src/java/server/play/player_abilities.rs b/pumpkin-protocol/src/java/server/play/player_abilities.rs index 768c36685..53f4221b0 100644 --- a/pumpkin-protocol/src/java/server/play/player_abilities.rs +++ b/pumpkin-protocol/src/java/server/play/player_abilities.rs @@ -8,15 +8,14 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PLAYER_ABILITIES)] pub struct SPlayerAbilities { pub flags: i8, } -impl ServerPacket for SPlayerAbilities { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerAbilities { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { flags: bytebuf.get_i8()?, }) diff --git a/pumpkin-protocol/src/java/server/play/player_action.rs b/pumpkin-protocol/src/java/server/play/player_action.rs index d1047fd39..a2d52e1e0 100644 --- a/pumpkin-protocol/src/java/server/play/player_action.rs +++ b/pumpkin-protocol/src/java/server/play/player_action.rs @@ -6,7 +6,6 @@ use pumpkin_data::packet::serverbound::PLAY_PLAYER_ACTION; use pumpkin_macros::java_packet; use pumpkin_util::math::position::BlockPos; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -18,9 +17,9 @@ pub struct SPlayerAction { pub sequence: VarInt, } -impl ServerPacket for SPlayerAction { +impl<'a> ServerPacket<'a> for SPlayerAction { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/player_command.rs b/pumpkin-protocol/src/java/server/play/player_command.rs index 1661600e9..e32a47a8e 100644 --- a/pumpkin-protocol/src/java/server/play/player_command.rs +++ b/pumpkin-protocol/src/java/server/play/player_command.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_PLAYER_COMMAND; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; @@ -33,8 +31,8 @@ pub enum Action { pub struct InvalidAction; -impl ServerPacket for SPlayerCommand { - fn read(mut read: impl Read, version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerCommand { + fn read(read: &mut &'a [u8], version: &JavaMinecraftVersion) -> Result { let entity_id = read.get_var_int()?; let action_id = read.get_var_int()?; let jump_boost = read.get_var_int()?; diff --git a/pumpkin-protocol/src/java/server/play/player_ground.rs b/pumpkin-protocol/src/java/server/play/player_ground.rs index 181ea06c0..d7d673d54 100644 --- a/pumpkin-protocol/src/java/server/play/player_ground.rs +++ b/pumpkin-protocol/src/java/server/play/player_ground.rs @@ -5,15 +5,14 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_MOVE_PLAYER_STATUS_ONLY; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_MOVE_PLAYER_STATUS_ONLY)] pub struct SSetPlayerGround { pub on_ground: bool, } -impl ServerPacket for SSetPlayerGround { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetPlayerGround { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { on_ground: bytebuf.get_bool()?, }) diff --git a/pumpkin-protocol/src/java/server/play/player_input.rs b/pumpkin-protocol/src/java/server/play/player_input.rs index 889802879..bd7f01a34 100644 --- a/pumpkin-protocol/src/java/server/play/player_input.rs +++ b/pumpkin-protocol/src/java/server/play/player_input.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_PLAYER_INPUT; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PLAYER_INPUT)] pub struct SPlayerInput { @@ -23,8 +22,8 @@ impl SPlayerInput { pub const SPRINT: i8 = 64; } -impl ServerPacket for SPlayerInput { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerInput { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { input: bytebuf.get_i8()?, }) diff --git a/pumpkin-protocol/src/java/server/play/player_loaded.rs b/pumpkin-protocol/src/java/server/play/player_loaded.rs index 6f6bb8ad2..20171b093 100644 --- a/pumpkin-protocol/src/java/server/play/player_loaded.rs +++ b/pumpkin-protocol/src/java/server/play/player_loaded.rs @@ -2,14 +2,13 @@ use crate::{ServerPacket, ser::ReadingError}; use pumpkin_data::packet::serverbound::PLAY_PLAYER_LOADED; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_PLAYER_LOADED)] pub struct SPlayerLoaded; -impl ServerPacket for SPlayerLoaded { +impl<'a> ServerPacket<'a> for SPlayerLoaded { fn read( - _bytebuf: impl Read, + _bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self) diff --git a/pumpkin-protocol/src/java/server/play/player_position.rs b/pumpkin-protocol/src/java/server/play/player_position.rs index e27a5f7bc..bbd2d1ed8 100644 --- a/pumpkin-protocol/src/java/server/play/player_position.rs +++ b/pumpkin-protocol/src/java/server/play/player_position.rs @@ -7,7 +7,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { @@ -16,8 +15,8 @@ pub struct SPlayerPosition { pub collision: u8, } -impl ServerPacket for SPlayerPosition { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerPosition { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { position: Vector3::new( bytebuf.get_f64_be()?, diff --git a/pumpkin-protocol/src/java/server/play/player_position_rotation.rs b/pumpkin-protocol/src/java/server/play/player_position_rotation.rs index 4c47990c9..8b6ad6bdf 100644 --- a/pumpkin-protocol/src/java/server/play/player_position_rotation.rs +++ b/pumpkin-protocol/src/java/server/play/player_position_rotation.rs @@ -7,7 +7,6 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; pub const FLAG_ON_GROUND: u8 = 0x01; pub const FLAG_IN_WALL: u8 = 0x02; @@ -21,8 +20,8 @@ pub struct SPlayerPositionRotation { pub collision: u8, } -impl ServerPacket for SPlayerPositionRotation { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerPositionRotation { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { position: Vector3::new( bytebuf.get_f64_be()?, diff --git a/pumpkin-protocol/src/java/server/play/player_rotation.rs b/pumpkin-protocol/src/java/server/play/player_rotation.rs index 70a07ad83..0dcb64250 100644 --- a/pumpkin-protocol/src/java/server/play/player_rotation.rs +++ b/pumpkin-protocol/src/java/server/play/player_rotation.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_MOVE_PLAYER_ROT; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_MOVE_PLAYER_ROT)] pub struct SPlayerRotation { @@ -14,8 +13,8 @@ pub struct SPlayerRotation { pub ground: bool, } -impl ServerPacket for SPlayerRotation { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerRotation { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { yaw: bytebuf.get_f32_be()?, pitch: bytebuf.get_f32_be()?, diff --git a/pumpkin-protocol/src/java/server/play/player_session.rs b/pumpkin-protocol/src/java/server/play/player_session.rs index 5b218a8c9..13ab4169e 100644 --- a/pumpkin-protocol/src/java/server/play/player_session.rs +++ b/pumpkin-protocol/src/java/server/play/player_session.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_CHAT_SESSION_UPDATE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; @@ -18,22 +16,24 @@ pub struct SPlayerSession { pub key_signature: Box<[u8]>, } -impl ServerPacket for SPlayerSession { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SPlayerSession { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { let session_id = read.get_uuid()?; let expires_at = read.get_i64_be()?; let public_key_length = read.get_var_int()?.0 as usize; - let public_key = read.read_boxed_slice(public_key_length)?; + let mut public_key = vec![0u8; public_key_length]; + read.read_bytes_to_buf(&mut public_key)?; let key_signature_length = read.get_var_int()?.0 as usize; - let key_signature = read.read_boxed_slice(key_signature_length)?; + let mut key_signature = vec![0u8; key_signature_length]; + read.read_bytes_to_buf(&mut key_signature)?; Ok(Self { session_id, expires_at, - public_key, - key_signature, + public_key: public_key.into_boxed_slice(), + key_signature: key_signature.into_boxed_slice(), }) } } diff --git a/pumpkin-protocol/src/java/server/play/recipe_book_change_settings.rs b/pumpkin-protocol/src/java/server/play/recipe_book_change_settings.rs index 1e503bbe5..2e7222c54 100644 --- a/pumpkin-protocol/src/java/server/play/recipe_book_change_settings.rs +++ b/pumpkin-protocol/src/java/server/play/recipe_book_change_settings.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_RECIPE_BOOK_CHANGE_SETTINGS; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -16,8 +15,8 @@ pub struct SRecipeBookChangeSettings { pub is_filtering: bool, } -impl ServerPacket for SRecipeBookChangeSettings { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SRecipeBookChangeSettings { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { book_type: bytebuf.get_var_int()?, is_open: bytebuf.get_bool()?, diff --git a/pumpkin-protocol/src/java/server/play/recipe_book_seen_recipe.rs b/pumpkin-protocol/src/java/server/play/recipe_book_seen_recipe.rs index 328ec5832..32dc86716 100644 --- a/pumpkin-protocol/src/java/server/play/recipe_book_seen_recipe.rs +++ b/pumpkin-protocol/src/java/server/play/recipe_book_seen_recipe.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_RECIPE_BOOK_SEEN_RECIPE; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -14,8 +13,8 @@ pub struct SRecipeBookSeenRecipe { pub recipe_display_id: VarInt, } -impl ServerPacket for SRecipeBookSeenRecipe { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SRecipeBookSeenRecipe { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { recipe_display_id: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/rename_item.rs b/pumpkin-protocol/src/java/server/play/rename_item.rs index 9fc0b2a06..8ff7d31dd 100644 --- a/pumpkin-protocol/src/java/server/play/rename_item.rs +++ b/pumpkin-protocol/src/java/server/play/rename_item.rs @@ -1,22 +1,21 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_RENAME_ITEM; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[derive(Debug)] #[java_packet(PLAY_RENAME_ITEM)] -pub struct SRenameItem { - pub item_name: String, +pub struct SRenameItem<'a> { + pub item_name: &'a str, } -impl ServerPacket for SRenameItem { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SRenameItem<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { - item_name: bytebuf.get_str_bounded(32767)?.into_string(), + item_name: bytebuf.get_str_bounded_borrowed(32767)?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/seen_advancement.rs b/pumpkin-protocol/src/java/server/play/seen_advancement.rs index c2f0b439a..af8c5a162 100644 --- a/pumpkin-protocol/src/java/server/play/seen_advancement.rs +++ b/pumpkin-protocol/src/java/server/play/seen_advancement.rs @@ -1,12 +1,11 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_SEEN_ADVANCEMENTS; use pumpkin_macros::java_packet; use pumpkin_util::identifier::Identifier; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[derive(Debug)] #[java_packet(PLAY_SEEN_ADVANCEMENTS)] @@ -15,14 +14,14 @@ pub enum SSeenAdvancement { CloseTab, } -impl ServerPacket for SSeenAdvancement { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSeenAdvancement { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { let action = bytebuf.get_var_int()?; match action.0 { 0 => { - let id_str = bytebuf.get_str()?; + let id_str = bytebuf.get_str_borrowed()?; let id = - Identifier::parse(&id_str).map_err(|e| ReadingError::Message(e.to_string()))?; + Identifier::parse(id_str).map_err(|e| ReadingError::Message(e.to_string()))?; Ok(Self::OpenTab(id)) } 1 => Ok(Self::CloseTab), diff --git a/pumpkin-protocol/src/java/server/play/select_trade.rs b/pumpkin-protocol/src/java/server/play/select_trade.rs index 467f5323f..267c3271c 100644 --- a/pumpkin-protocol/src/java/server/play/select_trade.rs +++ b/pumpkin-protocol/src/java/server/play/select_trade.rs @@ -8,15 +8,14 @@ use crate::{ ser::{NetworkReadExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_SELECT_TRADE)] pub struct SSelectTrade { pub selected_slot: VarInt, } -impl ServerPacket for SSelectTrade { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSelectTrade { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { selected_slot: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/set_beacon.rs b/pumpkin-protocol/src/java/server/play/set_beacon.rs index deff4c742..5e1b8cbde 100644 --- a/pumpkin-protocol/src/java/server/play/set_beacon.rs +++ b/pumpkin-protocol/src/java/server/play/set_beacon.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_SET_BEACON; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::codec::var_int::VarInt; @@ -15,8 +14,8 @@ pub struct SSetBeacon { pub secondary_effect: Option, } -impl ServerPacket for SSetBeacon { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetBeacon { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { primary_effect: bytebuf.get_option(NetworkReadExt::get_var_int)?, secondary_effect: bytebuf.get_option(NetworkReadExt::get_var_int)?, diff --git a/pumpkin-protocol/src/java/server/play/set_command_block.rs b/pumpkin-protocol/src/java/server/play/set_command_block.rs index 5318d0e7b..65ebd9ab8 100644 --- a/pumpkin-protocol/src/java/server/play/set_command_block.rs +++ b/pumpkin-protocol/src/java/server/play/set_command_block.rs @@ -1,19 +1,18 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_SET_COMMAND_BLOCK; use pumpkin_macros::java_packet; use pumpkin_util::math::position::BlockPos; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::codec::var_int::VarInt; #[java_packet(PLAY_SET_COMMAND_BLOCK)] -pub struct SSetCommandBlock { +pub struct SSetCommandBlock<'a> { pub pos: BlockPos, - pub command: String, + pub command: &'a str, pub mode: VarInt, /// Operation mode flags @@ -23,11 +22,11 @@ pub struct SSetCommandBlock { pub flags: i8, } -impl ServerPacket for SSetCommandBlock { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetCommandBlock<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { pos: BlockPos::from_i64(bytebuf.get_i64_be()?), - command: bytebuf.get_str_bounded(32767)?.into_string(), + command: bytebuf.get_str_bounded_borrowed(32767)?, mode: bytebuf.get_var_int()?, flags: bytebuf.get_i8()?, }) diff --git a/pumpkin-protocol/src/java/server/play/set_creative_slot.rs b/pumpkin-protocol/src/java/server/play/set_creative_slot.rs index eff1c441d..3b6d41bcd 100644 --- a/pumpkin-protocol/src/java/server/play/set_creative_slot.rs +++ b/pumpkin-protocol/src/java/server/play/set_creative_slot.rs @@ -14,9 +14,9 @@ pub struct SSetCreativeSlot { pub clicked_item: ItemStackSerializer<'static>, } -impl ServerPacket for SSetCreativeSlot { +impl<'a> ServerPacket<'a> for SSetCreativeSlot { fn read( - mut read: impl std::io::Read, + mut read: &mut &'a [u8], _version: &JavaMinecraftVersion, ) -> Result { let slot = read.get_i16_be()?; diff --git a/pumpkin-protocol/src/java/server/play/set_held_item.rs b/pumpkin-protocol/src/java/server/play/set_held_item.rs index c089010bd..2201618de 100644 --- a/pumpkin-protocol/src/java/server/play/set_held_item.rs +++ b/pumpkin-protocol/src/java/server/play/set_held_item.rs @@ -5,15 +5,14 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_SET_CARRIED_ITEM; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_SET_CARRIED_ITEM)] pub struct SSetHeldItem { pub slot: i16, } -impl ServerPacket for SSetHeldItem { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetHeldItem { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { slot: bytebuf.get_i16_be()?, }) diff --git a/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs b/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs index 7dba9b126..6b6917d60 100644 --- a/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs +++ b/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs @@ -1,36 +1,35 @@ use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_data::packet::serverbound::PLAY_SET_JIGSAW_BLOCK; use pumpkin_macros::java_packet; use pumpkin_util::math::position::BlockPos; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::codec::var_int::VarInt; #[java_packet(PLAY_SET_JIGSAW_BLOCK)] -pub struct SSetJigsawBlock { +pub struct SSetJigsawBlock<'a> { pub pos: BlockPos, - pub name: String, - pub target: String, - pub pool: String, - pub final_state: String, - pub joint: String, + pub name: &'a str, + pub target: &'a str, + pub pool: &'a str, + pub final_state: &'a str, + pub joint: &'a str, pub selection_priority: VarInt, pub placement_priority: VarInt, } -impl ServerPacket for SSetJigsawBlock { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetJigsawBlock<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { pos: BlockPos::from_i64(bytebuf.get_i64_be()?), - name: bytebuf.get_str_bounded(32767)?.into_string(), - target: bytebuf.get_str_bounded(32767)?.into_string(), - pool: bytebuf.get_str_bounded(32767)?.into_string(), - final_state: bytebuf.get_str_bounded(32767)?.into_string(), - joint: bytebuf.get_str_bounded(32767)?.into_string(), + name: bytebuf.get_str_bounded_borrowed(32767)?, + target: bytebuf.get_str_bounded_borrowed(32767)?, + pool: bytebuf.get_str_bounded_borrowed(32767)?, + final_state: bytebuf.get_str_bounded_borrowed(32767)?, + joint: bytebuf.get_str_bounded_borrowed(32767)?, selection_priority: bytebuf.get_var_int()?, placement_priority: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/set_test_block.rs b/pumpkin-protocol/src/java/server/play/set_test_block.rs index 846e50ac3..8f329fe47 100644 --- a/pumpkin-protocol/src/java/server/play/set_test_block.rs +++ b/pumpkin-protocol/src/java/server/play/set_test_block.rs @@ -4,24 +4,27 @@ use pumpkin_util::math::position::BlockPos; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; use pumpkin_util::version::JavaMinecraftVersion; use std::io::Read; #[java_packet(PLAY_SET_TEST_BLOCK)] -pub struct SSetTestBlock { +pub struct SSetTestBlock<'a> { pub position: BlockPos, pub mode: TestBlockMode, - pub message: String, + pub message: &'a str, } -impl ServerPacket for SSetTestBlock { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSetTestBlock<'a> { + fn read( + mut bytebuf: &mut &'a [u8], + _version: &JavaMinecraftVersion, + ) -> Result { Ok(Self { position: BlockPos::from_i64(bytebuf.get_i64_be()?), mode: TestBlockMode::read(&mut bytebuf)?, - message: bytebuf.get_str()?.into_string(), + message: bytebuf.get_str_borrowed()?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/swing_arm.rs b/pumpkin-protocol/src/java/server/play/swing_arm.rs index d3a03e589..2a1a92030 100644 --- a/pumpkin-protocol/src/java/server/play/swing_arm.rs +++ b/pumpkin-protocol/src/java/server/play/swing_arm.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_SWING; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -14,8 +13,8 @@ pub struct SSwingArm { pub hand: VarInt, } -impl ServerPacket for SSwingArm { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SSwingArm { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { hand: bytebuf.get_var_int()?, }) diff --git a/pumpkin-protocol/src/java/server/play/teleport_to_entity.rs b/pumpkin-protocol/src/java/server/play/teleport_to_entity.rs index 1b074b395..f7f0693f8 100644 --- a/pumpkin-protocol/src/java/server/play/teleport_to_entity.rs +++ b/pumpkin-protocol/src/java/server/play/teleport_to_entity.rs @@ -5,16 +5,15 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_TELEPORT_TO_ENTITY; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; #[java_packet(PLAY_TELEPORT_TO_ENTITY)] pub struct STeleportToEntity { pub target: uuid::Uuid, } -impl ServerPacket for STeleportToEntity { +impl<'a> ServerPacket<'a> for STeleportToEntity { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/test_instance_block_action.rs b/pumpkin-protocol/src/java/server/play/test_instance_block_action.rs index 0897c2e79..970c3bd0b 100644 --- a/pumpkin-protocol/src/java/server/play/test_instance_block_action.rs +++ b/pumpkin-protocol/src/java/server/play/test_instance_block_action.rs @@ -12,18 +12,18 @@ use pumpkin_util::version::JavaMinecraftVersion; use std::io::Read; #[java_packet(PLAY_TEST_INSTANCE_BLOCK_ACTION)] -pub struct STestInstanceBlockAction { +pub struct STestInstanceBlockAction<'a> { pub pos: BlockPos, pub action: TestInstanceBlockAction, - pub data: TestInstanceBlockData, + pub data: TestInstanceBlockData<'a>, } -impl ServerPacket for STestInstanceBlockAction { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for STestInstanceBlockAction<'a> { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { pos: BlockPos::from_i64(bytebuf.get_i64_be()?), - action: TestInstanceBlockAction::read(&mut bytebuf)?, - data: TestInstanceBlockData::read(&mut bytebuf)?, + action: TestInstanceBlockAction::read(bytebuf)?, + data: TestInstanceBlockData::read(bytebuf)?, }) } } @@ -72,18 +72,18 @@ impl VarIntVector3 { } } -pub struct TestInstanceBlockData { - pub test: Option, +pub struct TestInstanceBlockData<'a> { + pub test: Option<&'a str>, pub size: VarIntVector3, pub rotation: pumpkin_data::block_rotation::Rotation, pub ignore_entities: bool, pub status: TestInstanceBlockStatus, - pub error_message: Option, + pub error_message: Option<&'a str>, } -impl TestInstanceBlockData { - fn read(bytebuf: &mut impl Read) -> Result { - let test = bytebuf.get_option(|b| b.get_str().map(String::from))?; +impl<'a> TestInstanceBlockData<'a> { + fn read(bytebuf: &mut &'a [u8]) -> Result { + let test = bytebuf.get_option(crate::ser::NetworkReadSliceExt::get_str_borrowed)?; let size = VarIntVector3::read(bytebuf)?; let rotation = match bytebuf.get_var_int()?.0 { 0 => pumpkin_data::block_rotation::Rotation::None, @@ -104,7 +104,8 @@ impl TestInstanceBlockData { )); } }; - let error_message = bytebuf.get_option(|b| b.get_str().map(String::from))?; + let error_message = + bytebuf.get_option(crate::ser::NetworkReadSliceExt::get_str_borrowed)?; Ok(Self { test, diff --git a/pumpkin-protocol/src/java/server/play/update_sign.rs b/pumpkin-protocol/src/java/server/play/update_sign.rs index fbd7ed22b..98799582d 100644 --- a/pumpkin-protocol/src/java/server/play/update_sign.rs +++ b/pumpkin-protocol/src/java/server/play/update_sign.rs @@ -1,35 +1,33 @@ -use std::io::Read; - use pumpkin_data::packet::serverbound::PLAY_SIGN_UPDATE; use pumpkin_macros::java_packet; use pumpkin_util::{math::position::BlockPos, version::JavaMinecraftVersion}; use crate::{ ServerPacket, - ser::{NetworkReadExt, ReadingError}, + ser::{NetworkReadExt, NetworkReadSliceExt, ReadingError}, }; #[java_packet(PLAY_SIGN_UPDATE)] -pub struct SUpdateSign { +pub struct SUpdateSign<'a> { pub location: BlockPos, pub is_front_text: bool, - pub line_1: Box, - pub line_2: Box, - pub line_3: Box, - pub line_4: Box, + pub line_1: &'a str, + pub line_2: &'a str, + pub line_3: &'a str, + pub line_4: &'a str, } const MAX_LINE_LENGTH: usize = 386; -impl ServerPacket for SUpdateSign { - fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SUpdateSign<'a> { + fn read(read: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { location: BlockPos::from_i64(read.get_i64_be()?), is_front_text: read.get_bool()?, - line_1: read.get_str_bounded(MAX_LINE_LENGTH)?, - line_2: read.get_str_bounded(MAX_LINE_LENGTH)?, - line_3: read.get_str_bounded(MAX_LINE_LENGTH)?, - line_4: read.get_str_bounded(MAX_LINE_LENGTH)?, + line_1: read.get_str_bounded_borrowed(MAX_LINE_LENGTH)?, + line_2: read.get_str_bounded_borrowed(MAX_LINE_LENGTH)?, + line_3: read.get_str_bounded_borrowed(MAX_LINE_LENGTH)?, + line_4: read.get_str_bounded_borrowed(MAX_LINE_LENGTH)?, }) } } diff --git a/pumpkin-protocol/src/java/server/play/use_item.rs b/pumpkin-protocol/src/java/server/play/use_item.rs index 17f725960..9510b34f9 100644 --- a/pumpkin-protocol/src/java/server/play/use_item.rs +++ b/pumpkin-protocol/src/java/server/play/use_item.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::PLAY_USE_ITEM; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -18,9 +17,9 @@ pub struct SUseItem { pub pitch: f32, } -impl ServerPacket for SUseItem { +impl<'a> ServerPacket<'a> for SUseItem { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/use_item_on.rs b/pumpkin-protocol/src/java/server/play/use_item_on.rs index 95f0b6ecd..cc4c83d4f 100644 --- a/pumpkin-protocol/src/java/server/play/use_item_on.rs +++ b/pumpkin-protocol/src/java/server/play/use_item_on.rs @@ -6,7 +6,6 @@ use pumpkin_data::packet::serverbound::PLAY_USE_ITEM_ON; use pumpkin_macros::java_packet; use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; use crate::VarInt; @@ -21,8 +20,8 @@ pub struct SUseItemOn { pub sequence: VarInt, } -impl ServerPacket for SUseItemOn { - fn read(mut bytebuf: impl Read, _version: &JavaMinecraftVersion) -> Result { +impl<'a> ServerPacket<'a> for SUseItemOn { + fn read(bytebuf: &mut &'a [u8], _version: &JavaMinecraftVersion) -> Result { Ok(Self { hand: bytebuf.get_var_int()?, position: BlockPos::from_i64(bytebuf.get_i64_be()?), diff --git a/pumpkin-protocol/src/java/server/status/ping_request.rs b/pumpkin-protocol/src/java/server/status/ping_request.rs index 6ac29ccdf..cfb6a83b2 100644 --- a/pumpkin-protocol/src/java/server/status/ping_request.rs +++ b/pumpkin-protocol/src/java/server/status/ping_request.rs @@ -5,7 +5,6 @@ use crate::{ use pumpkin_data::packet::serverbound::STATUS_PING_REQUEST; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; /// Sent by the client to measure the round-trip time (latency) to the server. /// @@ -16,9 +15,9 @@ pub struct SStatusPingRequest { pub payload: i64, } -impl ServerPacket for SStatusPingRequest { +impl<'a> ServerPacket<'a> for SStatusPingRequest { fn read( - mut bytebuf: impl Read, + bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self { diff --git a/pumpkin-protocol/src/java/server/status/status_request.rs b/pumpkin-protocol/src/java/server/status/status_request.rs index e3bc8b54e..ca6065241 100644 --- a/pumpkin-protocol/src/java/server/status/status_request.rs +++ b/pumpkin-protocol/src/java/server/status/status_request.rs @@ -2,7 +2,6 @@ use crate::{ServerPacket, ser::ReadingError}; use pumpkin_data::packet::serverbound::STATUS_STATUS_REQUEST; use pumpkin_macros::java_packet; use pumpkin_util::version::JavaMinecraftVersion; -use std::io::Read; /// Sent by the client to request the server's current status information. /// @@ -11,9 +10,9 @@ use std::io::Read; #[java_packet(STATUS_STATUS_REQUEST)] pub struct SStatusRequest; -impl ServerPacket for SStatusRequest { +impl<'a> ServerPacket<'a> for SStatusRequest { fn read( - _bytebuf: impl Read, + _bytebuf: &mut &'a [u8], _protocol_version: &JavaMinecraftVersion, ) -> Result { Ok(Self) diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 3a7bc6a11..e4a8602a1 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -253,8 +253,8 @@ pub trait ClientPacket: MultiVersionJavaPacket { ) -> Result<(), WritingError>; } -pub trait ServerPacket: MultiVersionJavaPacket + Sized { - fn read(read: impl Read, version: &JavaMinecraftVersion) -> Result; +pub trait ServerPacket<'a>: MultiVersionJavaPacket + Sized { + fn read(read: &mut &'a [u8], version: &JavaMinecraftVersion) -> Result; } pub trait BClientPacket: Packet { diff --git a/pumpkin-protocol/src/ser/mod.rs b/pumpkin-protocol/src/ser/mod.rs index 5f9ae12d1..dd47d6a3e 100644 --- a/pumpkin-protocol/src/ser/mod.rs +++ b/pumpkin-protocol/src/ser/mod.rs @@ -1,4 +1,5 @@ use core::str; +use std::borrow::Cow; use std::io::{Read, Write}; use crate::{ @@ -61,34 +62,40 @@ pub trait NetworkReadExt { fn get_i128_be(&mut self) -> Result; fn get_u128_be(&mut self) -> Result; + #[inline] fn get_i16(&mut self) -> Result { self.get_i16_be() } + #[inline] fn get_u16(&mut self) -> Result { self.get_u16_be() } + #[inline] fn get_i32(&mut self) -> Result { self.get_i32_be() } + #[inline] fn get_u32(&mut self) -> Result { self.get_u32_be() } + #[inline] fn get_i64(&mut self) -> Result { self.get_i64_be() } + #[inline] fn get_u64(&mut self) -> Result { self.get_u64_be() } + #[inline] fn get_f32(&mut self) -> Result { self.get_f32_be() } + #[inline] fn get_f64(&mut self) -> Result { self.get_f64_be() } - fn read_boxed_slice(&mut self, count: usize) -> Result, ReadingError>; - - fn read_remaining_to_boxed_slice(&mut self, bound: usize) -> Result, ReadingError>; + fn read_bytes_to_buf(&mut self, buf: &mut [u8]) -> Result<(), ReadingError>; fn get_bool(&mut self) -> Result; fn get_var_int(&mut self) -> Result; @@ -96,23 +103,154 @@ pub trait NetworkReadExt { fn get_var_long(&mut self) -> Result; fn get_var_ulong(&mut self) -> Result; fn get_str_bounded(&mut self, bound: usize) -> Result, ReadingError>; - fn get_str(&mut self) -> Result, ReadingError>; + #[inline] + fn get_str(&mut self) -> Result, ReadingError> { + self.get_str_bounded(i32::MAX as usize) + } fn get_uuid(&mut self) -> Result; fn get_fixed_bitset(&mut self, bits: usize) -> Result; + #[inline] fn get_option( &mut self, parse: impl FnOnce(&mut Self) -> Result, - ) -> Result, ReadingError>; + ) -> Result, ReadingError> { + if self.get_bool()? { + Ok(Some(parse(self)?)) + } else { + Ok(None) + } + } + #[inline] fn get_list( &mut self, parse: impl Fn(&mut Self) -> Result, - ) -> Result, ReadingError>; + ) -> Result, ReadingError> { + const MAX_LIST_SIZE: usize = 65536; + + let len = self.get_var_int()?.0 as usize; + if len > MAX_LIST_SIZE { + return Err(ReadingError::TooLarge(format!( + "List length {len} exceeds limit" + ))); + } + let mut list = Vec::with_capacity(len); + for _ in 0..len { + list.push(parse(self)?); + } + Ok(list) + } +} + +pub trait NetworkReadSliceExt<'a> { + fn get_str_borrowed(&mut self) -> Result<&'a str, ReadingError>; + fn get_str_bounded_borrowed(&mut self, bound: usize) -> Result<&'a str, ReadingError>; + fn read_slice_borrowed(&mut self, count: usize) -> Result<&'a [u8], ReadingError>; + fn read_remaining_slice_borrowed(&mut self, bound: usize) -> Result<&'a [u8], ReadingError>; + + #[inline] + fn read_cow_slice_borrowed(&mut self, count: usize) -> Result, ReadingError> { + Ok(Cow::Borrowed(self.read_slice_borrowed(count)?)) + } + + #[inline] + fn read_remaining_to_cow_slice_borrowed( + &mut self, + bound: usize, + ) -> Result, ReadingError> { + Ok(Cow::Borrowed(self.read_remaining_slice_borrowed(bound)?)) + } + + #[inline] + fn get_cow_str_borrowed(&mut self) -> Result, ReadingError> { + self.get_cow_str_bounded_borrowed(i32::MAX as usize) + } + + #[inline] + fn get_cow_str_bounded_borrowed(&mut self, bound: usize) -> Result, ReadingError> { + Ok(Cow::Borrowed(self.get_str_bounded_borrowed(bound)?)) + } +} + +impl<'a> NetworkReadSliceExt<'a> for &'a [u8] { + #[inline] + fn read_slice_borrowed(&mut self, count: usize) -> Result<&'a [u8], ReadingError> { + if self.len() < count { + return Err(ReadingError::Incomplete(format!( + "EOF, Tried to read {count} bytes but only {} bytes left", + self.len() + ))); + } + let (head, tail) = self.split_at(count); + *self = tail; + Ok(head) + } + + #[inline] + fn read_remaining_slice_borrowed(&mut self, bound: usize) -> Result<&'a [u8], ReadingError> { + if self.len() > bound { + return Err(ReadingError::TooLarge( + "Read remaining too long".to_string(), + )); + } + let slice = *self; + *self = &[]; + Ok(slice) + } + + #[inline] + fn get_str_bounded_borrowed(&mut self, bound: usize) -> Result<&'a str, ReadingError> { + let bytes_len = self.get_var_uint()?.0 as usize; + + let maximum_utf8_bytes = bound.saturating_mul(3); + if bytes_len > maximum_utf8_bytes { + return Err(ReadingError::TooLarge(format!( + "string has too many bytes ({bytes_len} > {maximum_utf8_bytes})" + ))); + } + + let bytes = self.read_slice_borrowed(bytes_len)?; + let string = + std::str::from_utf8(bytes).map_err(|e| ReadingError::Message(e.to_string()))?; + + if string.encode_utf16().nth(bound).is_some() { + return Err(ReadingError::TooLarge(format!( + "string has too many UTF-16 characters (more than the maximum limit {bound})" + ))); + } + + Ok(string) + } + + #[inline] + fn get_str_borrowed(&mut self) -> Result<&'a str, ReadingError> { + self.get_str_bounded_borrowed(i32::MAX as usize) + } +} + +impl<'a, R: NetworkReadSliceExt<'a> + ?Sized> NetworkReadSliceExt<'a> for &mut R { + #[inline] + fn get_str_borrowed(&mut self) -> Result<&'a str, ReadingError> { + (**self).get_str_borrowed() + } + #[inline] + fn get_str_bounded_borrowed(&mut self, bound: usize) -> Result<&'a str, ReadingError> { + (**self).get_str_bounded_borrowed(bound) + } + #[inline] + fn read_slice_borrowed(&mut self, count: usize) -> Result<&'a [u8], ReadingError> { + (**self).read_slice_borrowed(count) + } + #[inline] + fn read_remaining_slice_borrowed(&mut self, bound: usize) -> Result<&'a [u8], ReadingError> { + (**self).read_remaining_slice_borrowed(bound) + } } macro_rules! get_number_be { ($name:ident, $type:ty) => { + #[inline] fn $name(&mut self) -> Result<$type, ReadingError> { let mut buf = [0u8; std::mem::size_of::<$type>()]; self.read_exact(&mut buf) @@ -137,58 +275,38 @@ impl NetworkReadExt for R { get_number_be!(get_f32_be, f32); get_number_be!(get_f64_be, f64); - fn read_boxed_slice(&mut self, length: usize) -> Result, ReadingError> { - // Increase this to at least 2MB to handle larger Bedrock batches - const MAX_SLICE_LENGTH: usize = 2 * 1024 * 1024; // 2MB - if !(0..=MAX_SLICE_LENGTH).contains(&length) { - return Err(ReadingError::Message(format!( - "read_boxed_slice: length {length} out of bounds" - ))); - } - let mut buf = vec![0u8; length]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(buf.into()) - } - - fn read_remaining_to_boxed_slice(&mut self, bound: usize) -> Result, ReadingError> { - let mut return_buf = Vec::new(); - - // Take one extra byte to check for exceeding bound - self.take(bound as u64 + 1) - .read_to_end(&mut return_buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - if return_buf.len() > bound { - return Err(ReadingError::TooLarge( - "Read remaining too long".to_string(), - )); - } - - Ok(return_buf.into_boxed_slice()) + #[inline] + fn read_bytes_to_buf(&mut self, buf: &mut [u8]) -> Result<(), ReadingError> { + self.read_exact(buf) + .map_err(|err| ReadingError::Incomplete(err.to_string())) } + #[inline] fn get_bool(&mut self) -> Result { let byte = self.get_u8()?; Ok(byte != 0) } + #[inline] fn get_var_int(&mut self) -> Result { VarInt::decode(self) } + #[inline] fn get_var_uint(&mut self) -> Result { VarUInt::decode(self) } + #[inline] fn get_var_long(&mut self) -> Result { VarLong::decode(self) } + #[inline] fn get_var_ulong(&mut self) -> Result { VarULong::decode(self) } + #[inline] fn get_str_bounded(&mut self, bound: usize) -> Result, ReadingError> { let bytes_len = self.get_var_uint()?.0 as usize; @@ -203,24 +321,39 @@ impl NetworkReadExt for R { ))); } - let data = self.read_boxed_slice(bytes_len)?; - let string = - std::str::from_utf8(&data).map_err(|e| ReadingError::Message(e.to_string()))?; + if bytes_len <= 128 { + let mut stack_buf = [0u8; 128]; + let slice = &mut stack_buf[..bytes_len]; + self.read_exact(slice) + .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - // Next, if we're able to find the (bound + 1)th UTF-16 character, the string is too big. - if string.encode_utf16().nth(bound).is_some() { - return Err(ReadingError::TooLarge(format!( - "string has too many UTF-16 characters (more than the maximum limit {bound})" - ))); + let string = + std::str::from_utf8(slice).map_err(|e| ReadingError::Message(e.to_string()))?; + + if string.encode_utf16().nth(bound).is_some() { + return Err(ReadingError::TooLarge(format!( + "string has too many UTF-16 characters (more than the maximum limit {bound})" + ))); + } + + Ok(string.into()) + } else { + let mut data = vec![0u8; bytes_len]; + self.read_bytes_to_buf(&mut data)?; + let string = + std::str::from_utf8(&data).map_err(|e| ReadingError::Message(e.to_string()))?; + + if string.encode_utf16().nth(bound).is_some() { + return Err(ReadingError::TooLarge(format!( + "string has too many UTF-16 characters (more than the maximum limit {bound})" + ))); + } + + Ok(string.into()) } - - Ok(string.into()) - } - - fn get_str(&mut self) -> Result, ReadingError> { - self.get_str_bounded(i32::MAX as usize) } + #[inline] fn get_uuid(&mut self) -> Result { let mut bytes = [0u8; 16]; self.read_exact(&mut bytes) @@ -228,40 +361,31 @@ impl NetworkReadExt for R { Ok(uuid::Uuid::from_bytes(bytes)) } + #[inline] fn get_fixed_bitset(&mut self, bits: usize) -> Result { - let bytes = self.read_boxed_slice(bits.div_ceil(8))?; - Ok(bytes) + let byte_count = bits.div_ceil(8); + let mut bytes = vec![0u8; byte_count]; + self.read_bytes_to_buf(&mut bytes)?; + Ok(bytes.into_boxed_slice()) + } +} + +#[inline] +pub fn read_remaining_bytes(read: &mut impl Read, bound: usize) -> Result, ReadingError> { + let mut return_buf = Vec::with_capacity(bound.min(1024)); + + // Take one extra byte to check for exceeding bound + read.take(bound as u64 + 1) + .read_to_end(&mut return_buf) + .map_err(|err| ReadingError::Incomplete(err.to_string()))?; + + if return_buf.len() > bound { + return Err(ReadingError::TooLarge( + "Read remaining too long".to_string(), + )); } - fn get_option( - &mut self, - parse: impl FnOnce(&mut Self) -> Result, - ) -> Result, ReadingError> { - if self.get_bool()? { - Ok(Some(parse(self)?)) - } else { - Ok(None) - } - } - - fn get_list( - &mut self, - parse: impl Fn(&mut Self) -> Result, - ) -> Result, ReadingError> { - const MAX_LIST_SIZE: usize = 65536; - - let len = self.get_var_int()?.0 as usize; - if len > MAX_LIST_SIZE { - return Err(ReadingError::TooLarge(format!( - "List length {len} exceeds limit" - ))); - } - let mut list = Vec::with_capacity(len); - for _ in 0..len { - list.push(parse(self)?); - } - Ok(list) - } + Ok(return_buf.into_boxed_slice()) } pub trait NetworkWriteExt { diff --git a/pumpkin-protocol/src/serial/deserializer.rs b/pumpkin-protocol/src/serial/deserializer.rs index b2411cc8d..f92282876 100644 --- a/pumpkin-protocol/src/serial/deserializer.rs +++ b/pumpkin-protocol/src/serial/deserializer.rs @@ -240,3 +240,162 @@ impl PacketRead for Option { bool::read(reader)?.then(|| T::read(reader)).transpose() } } + +impl<'a> crate::serial::PacketReadSlice<'a> for bool { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.is_empty() { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected bool byte")); + } + let b = buf[0]; + *buf = &buf[1..]; + Ok(b != 0) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for u8 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.is_empty() { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected u8")); + } + let b = buf[0]; + *buf = &buf[1..]; + Ok(b) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for i8 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + u8::read_slice(buf).map(|b| b as Self) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for i16 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 2 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected i16")); + } + let (bytes, rest) = buf.split_at(2); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for i32 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 4 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected i32")); + } + let (bytes, rest) = buf.split_at(4); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for i64 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 8 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected i64")); + } + let (bytes, rest) = buf.split_at(8); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for u16 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 2 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected u16")); + } + let (bytes, rest) = buf.split_at(2); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for u32 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 4 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected u32")); + } + let (bytes, rest) = buf.split_at(4); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for u64 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 8 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected u64")); + } + let (bytes, rest) = buf.split_at(8); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for f32 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 4 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected f32")); + } + let (bytes, rest) = buf.split_at(4); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for f64 { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 8 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected f64")); + } + let (bytes, rest) = buf.split_at(8); + *buf = rest; + Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for &'a str { + fn read_slice(buf: &mut &'a [u8]) -> Result { + crate::serial::read_str_slice(buf) + } +} + +impl<'a, T: crate::serial::PacketReadSlice<'a>> crate::serial::PacketReadSlice<'a> for Option { + fn read_slice(buf: &mut &'a [u8]) -> Result { + bool::read_slice(buf)? + .then(|| T::read_slice(buf)) + .transpose() + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for uuid::Uuid { + fn read_slice(buf: &mut &'a [u8]) -> Result { + if buf.len() < 16 { + return Err(Error::new(ErrorKind::UnexpectedEof, "expected Uuid")); + } + let (bytes, rest) = buf.split_at(16); + *buf = rest; + Ok(Self::from_bytes(bytes.try_into().unwrap())) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_int::VarInt { + fn read_slice(buf: &mut &'a [u8]) -> Result { + Self::read(buf) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_uint::VarUInt { + fn read_slice(buf: &mut &'a [u8]) -> Result { + Self::read(buf) + } +} + +impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_ulong::VarULong { + fn read_slice(buf: &mut &'a [u8]) -> Result { + Self::read(buf) + } +} diff --git a/pumpkin-protocol/src/serial/mod.rs b/pumpkin-protocol/src/serial/mod.rs index 6496f02eb..b84ff289b 100644 --- a/pumpkin-protocol/src/serial/mod.rs +++ b/pumpkin-protocol/src/serial/mod.rs @@ -16,3 +16,32 @@ pub trait PacketRead: Sized { Err(Error::other("Not implemented")) } } + +pub trait PacketReadSlice<'a>: Sized { + fn read_slice(buf: &mut &'a [u8]) -> Result; +} + +pub(crate) fn read_str_slice<'a>(buf: &mut &'a [u8]) -> Result<&'a str, Error> { + use crate::codec::var_uint::VarUInt; + use std::io::ErrorKind; + + const MAX_STRING_LENGTH: usize = 32767; + + let len = VarUInt::read(buf)?.0 as usize; + if len > MAX_STRING_LENGTH { + return Err(Error::new( + ErrorKind::InvalidData, + format!("String length {len} exceeds maximum of {MAX_STRING_LENGTH}"), + )); + } + if len > buf.len() { + return Err(Error::new( + ErrorKind::UnexpectedEof, + "Not enough bytes for string", + )); + } + let (str_bytes, rest) = buf.split_at(len); + *buf = rest; + std::str::from_utf8(str_bytes) + .map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid UTF-8 sequence")) +} diff --git a/pumpkin-protocol/src/serial/serializer.rs b/pumpkin-protocol/src/serial/serializer.rs index 6b0896137..d6ad9bd61 100644 --- a/pumpkin-protocol/src/serial/serializer.rs +++ b/pumpkin-protocol/src/serial/serializer.rs @@ -124,6 +124,13 @@ impl PacketWrite for String { } } +impl PacketWrite for str { + fn write(&self, writer: &mut W) -> Result<(), Error> { + VarUInt(self.len() as _).write(writer)?; + writer.write_all(self.as_bytes()) + } +} + impl PacketWrite for Vector3 { fn write(&self, writer: &mut W) -> Result<(), Error> { self.x.write(writer)?; diff --git a/pumpkin-util/src/text/color.rs b/pumpkin-util/src/text/color.rs index 86b7c64c9..d1cdf31dd 100644 --- a/pumpkin-util/src/text/color.rs +++ b/pumpkin-util/src/text/color.rs @@ -53,7 +53,7 @@ pub fn hsv_to_rgb(h: f32, s: f32, v: f32) -> (u8, u8, u8) { impl<'de> Deserialize<'de> for Color { fn deserialize>(deserializer: D) -> Result { - let s = String::deserialize(deserializer)?; + let s = <&str>::deserialize(deserializer)?; if s == "reset" { Ok(Self::Reset) @@ -73,9 +73,9 @@ impl<'de> Deserialize<'de> for Color { Ok(Self::Rgb(RGBColor::new(r, g, b))) } else { - Ok(Self::Named(NamedColor::try_from(s.as_str()).map_err( - |()| serde::de::Error::custom("Invalid named color"), - )?)) + Ok(Self::Named(NamedColor::try_from(s).map_err(|()| { + serde::de::Error::custom("Invalid named color") + })?)) } } } diff --git a/pumpkin-util/src/text/mod.rs b/pumpkin-util/src/text/mod.rs index 13aec54c6..ebc01d94a 100644 --- a/pumpkin-util/src/text/mod.rs +++ b/pumpkin-util/src/text/mod.rs @@ -541,10 +541,12 @@ impl TextComponent { #[must_use] pub fn from_legacy_string(input: &str) -> Self { let mut root = Self::text(""); - let parts: Vec<&str> = input.split('§').collect(); + let mut parts = input.split('§'); - if !parts[0].is_empty() { - root = root.add_child(Self::text(parts[0].to_string())); + if let Some(first) = parts.next() + && !first.is_empty() + { + root = root.add_child(Self::text(first.to_string())); } let mut current_color: Option = None; @@ -554,39 +556,34 @@ impl TextComponent { let mut strikethrough = false; let mut obfuscated = false; - let mut i = 1; - while i < parts.len() { - let part = parts[i]; + while let Some(part) = parts.next() { if part.is_empty() { - i += 1; continue; } - let mut chars = part.chars(); - let code = chars.next().unwrap_or(' ').to_ascii_lowercase(); + let code = part.chars().next().unwrap_or(' ').to_ascii_lowercase(); let remainder = &part[1..]; match code { - 'x' if i + 6 < parts.len() => { - let mut hex = String::new(); - for j in 1..=6 { - if let Some(c) = parts[i + j].chars().next() { - hex.push(c); + 'x' => { + let mut hex = [0u8; 6]; + let mut valid_hex = true; + for hex_byte in &mut hex { + if let Some(next_part) = parts.next() { + if let Some(c) = next_part.chars().next() { + *hex_byte = c as u8; + } else { + valid_hex = false; + break; + } + } else { + valid_hex = false; + break; } } - current_color = Color::from_hex_str(&hex); - - i += 6; - - let last_part = parts[i]; - if last_part.len() > 1 { - let mut child = Self::text(last_part[1..].to_string()); - if let Some(c) = current_color { - child = child.color(c); - } - root = root.add_child(child); + if valid_hex && let Ok(hex_str) = std::str::from_utf8(&hex) { + current_color = Color::from_hex_str(hex_str); } - i += 1; continue; } '0'..='9' | 'a'..='f' => { @@ -635,7 +632,6 @@ impl TextComponent { } root = root.add_child(child); } - i += 1; } root diff --git a/pumpkin-world/Cargo.toml b/pumpkin-world/Cargo.toml index f0115e552..fdae04d52 100644 --- a/pumpkin-world/Cargo.toml +++ b/pumpkin-world/Cargo.toml @@ -59,8 +59,8 @@ slotmap.workspace = true crossfire.workspace = true [dev-dependencies] +tempfile.workspace = true criterion = { workspace = true, features = ["html_reports", "async_tokio"] } -temp-dir.workspace = true # Deserialize NaN and Inf serde_json5.workspace = true diff --git a/pumpkin-world/src/chunk/format/mod.rs b/pumpkin-world/src/chunk/format/mod.rs index 2a823764c..de49d5ab9 100644 --- a/pumpkin-world/src/chunk/format/mod.rs +++ b/pumpkin-world/src/chunk/format/mod.rs @@ -222,12 +222,22 @@ impl ChunkData { let block_light = section_compound .get("BlockLight") .and_then(|tag| tag.extract_byte_array()) - .map(|arr| arr.iter().map(|&x| x as u8).collect::>()); + .map(|arr| unsafe { + Box::from(std::slice::from_raw_parts( + arr.as_ptr().cast::(), + arr.len(), + )) + }); let sky_light = section_compound .get("SkyLight") .and_then(|tag| tag.extract_byte_array()) - .map(|arr| arr.iter().map(|&x| x as u8).collect::>()); + .map(|arr| unsafe { + Box::from(std::slice::from_raw_parts( + arr.as_ptr().cast::(), + arr.len(), + )) + }); block_lights[index] = block_light.map_or(LightContainer::Empty(0), LightContainer::Full); diff --git a/pumpkin-world/src/chunk/format/pump.rs b/pumpkin-world/src/chunk/format/pump.rs index 2110357d7..e8c364eb6 100644 --- a/pumpkin-world/src/chunk/format/pump.rs +++ b/pumpkin-world/src/chunk/format/pump.rs @@ -156,7 +156,7 @@ mod tests { use serde::{Deserialize, Serialize}; use std::future::Future; use std::pin::Pin; - use temp_dir::TempDir; + use tempfile::TempDir; #[derive(Debug, Serialize, Deserialize, Clone)] struct MockChunk { @@ -201,7 +201,7 @@ mod tests { #[tokio::test] async fn pump_file_roundtrip() { let temp_dir = TempDir::new().unwrap(); - let file_path = temp_dir.child("r.0.0.pump"); + let file_path = temp_dir.path().join("r.0.0.pump"); let mut pump_file: PumpFile = PumpFile::default(); let chunk = MockChunk { diff --git a/pumpkin-world/src/world_info/anvil.rs b/pumpkin-world/src/world_info/anvil.rs index 9bd52ab20..3df9cc8a4 100644 --- a/pumpkin-world/src/world_info/anvil.rs +++ b/pumpkin-world/src/world_info/anvil.rs @@ -239,7 +239,7 @@ mod test { io::{Cursor, Read}, sync::LazyLock, }; - use temp_dir::TempDir; + use tempfile::TempDir; use crate::{ global_path, diff --git a/pumpkin/src/command/snbt/tests.rs b/pumpkin/src/command/snbt/tests.rs index 8f88b37e1..09687cb4c 100644 --- a/pumpkin/src/command/snbt/tests.rs +++ b/pumpkin/src/command/snbt/tests.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use pumpkin_nbt::{compound::NbtCompound, nbt_compound_tag, tag::NbtTag}; const BUILT_IN_LIKE_SUGGESTIONS: &[&str] = &["(", "bool", "false", "true", "uuid"]; @@ -339,19 +337,17 @@ fn operations() { fn maps() { assert_parse_ok!( "{x:5}", - NbtTag::Compound(NbtCompound { - child_tags: HashMap::from([("x".into(), NbtTag::Int(5))]) - }) + nbt_compound_tag! { + "x": NbtTag::Int(5) + } ); assert_parse_ok!( "{ a:1b,B :2uS , c:3L }", - NbtTag::Compound(NbtCompound { - child_tags: HashMap::from([ - ("a".into(), NbtTag::Byte(1)), - ("B".into(), NbtTag::Short(2)), - ("c".into(), NbtTag::Long(3)) - ]) - }) + nbt_compound_tag! { + "a": NbtTag::Byte(1), + "B": NbtTag::Short(2), + "c": NbtTag::Long(3) + } ); assert_parse_ok!( "{ a:1b, \"a\":2b, 'a':\"hi\" }", diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 615276e09..60b123cc8 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -3609,7 +3609,7 @@ impl Player { .await; } - pub async fn on_rename_item(self: &Arc, packet: SRenameItem) { + pub async fn on_rename_item(self: &Arc, packet: SRenameItem<'_>) { self.update_last_action_time(); let screen_handler_arc = self.current_screen_handler.lock().await.clone(); let mut screen_handler = screen_handler_arc.lock().await; @@ -3618,7 +3618,9 @@ impl Player { .as_any_mut() .downcast_mut::() { - anvil_handler.update_item_name(packet.item_name).await; + anvil_handler + .update_item_name(packet.item_name.to_string()) + .await; } } diff --git a/pumpkin/src/net/bedrock/mod.rs b/pumpkin/src/net/bedrock/mod.rs index 7a2fc6df8..5cb62b540 100644 --- a/pumpkin/src/net/bedrock/mod.rs +++ b/pumpkin/src/net/bedrock/mod.rs @@ -68,7 +68,7 @@ use pumpkin_protocol::{ }, codec::u24, packet::Packet, - serial::PacketRead, + serial::{PacketRead, PacketReadSlice}, }; use std::net::SocketAddr; use tokio::{ @@ -1156,11 +1156,11 @@ impl BedrockClient { .await; } SText::PACKET_ID => { - self.handle_chat_message(server, player, SText::read(reader)?) + self.handle_chat_message(server, player, SText::read_slice(reader)?) .await; } SCommandRequest::PACKET_ID => { - self.handle_chat_command(player, server, SCommandRequest::read(reader)?) + self.handle_chat_command(player, server, SCommandRequest::read_slice(reader)?) .await; } SSetLocalPlayerAsInitialized::PACKET_ID => { @@ -1181,7 +1181,7 @@ impl BedrockClient { self.handle_animate(player, server, &SAnimate::read(reader)?).await; } SEmote::PACKET_ID => { - self.handle_emote(player, server, SEmote::read(reader)?).await; + self.handle_emote(player, server, SEmote::read_slice(reader)?).await; } // SEmoteList::PACKET_ID => { // self.handle_emote_list(player, server, SEmoteList::read(reader)?); @@ -1190,7 +1190,7 @@ impl BedrockClient { self.handle_modal_form_response( player, server, - pumpkin_protocol::bedrock::server::modal_form_response::SModalFormResponse::read( + pumpkin_protocol::bedrock::server::modal_form_response::SModalFormResponse::read_slice( reader, )?, ) diff --git a/pumpkin/src/net/bedrock/play.rs b/pumpkin/src/net/bedrock/play.rs index 435038844..56c6d39a7 100644 --- a/pumpkin/src/net/bedrock/play.rs +++ b/pumpkin/src/net/bedrock/play.rs @@ -447,7 +447,7 @@ impl BedrockClient { } } - pub async fn handle_emote(&self, player: &Arc, _server: &Server, packet: SEmote) { + pub async fn handle_emote(&self, player: &Arc, _server: &Server, packet: SEmote<'_>) { if !player.has_client_loaded() { return; } @@ -1006,12 +1006,17 @@ impl BedrockClient { .await; } - pub async fn handle_chat_message(&self, server: &Server, player: &Arc, packet: SText) { + pub async fn handle_chat_message( + &self, + server: &Server, + player: &Arc, + packet: SText<'_>, + ) { let gameprofile = &player.gameprofile; send_cancellable! {{ server; - PlayerChatEvent::new(player.clone(), packet.message, vec![]); + PlayerChatEvent::new(player.clone(), packet.message.into_owned(), vec![]); 'after: { info!(" {}: {}", gameprofile.name, event.message); @@ -1178,11 +1183,11 @@ impl BedrockClient { &self, player: &Arc, server: &Arc, - packet: SCommandRequest, + packet: SCommandRequest<'_>, ) { let player_clone = player.clone(); let server_clone = server.clone(); - let command = packet.command.strip_prefix("/").unwrap_or(&packet.command); + let command = packet.command.strip_prefix('/').unwrap_or(&packet.command); send_cancellable! {{ server; @@ -1221,12 +1226,12 @@ impl BedrockClient { &self, player: &Arc, server: &Server, - packet: pumpkin_protocol::bedrock::server::modal_form_response::SModalFormResponse, + packet: pumpkin_protocol::bedrock::server::modal_form_response::SModalFormResponse<'_>, ) { let event = crate::plugin::api::events::player::bedrock_form_response::BedrockFormResponseEvent::new( player.clone(), packet.form_id.0 as u32, - packet.form_data, + packet.form_data.map(std::borrow::Cow::into_owned), ); let _ = server.plugin_manager.fire(event).await; } diff --git a/pumpkin/src/net/java/config.rs b/pumpkin/src/net/java/config.rs index 73e49acb8..573a46dc4 100644 --- a/pumpkin/src/net/java/config.rs +++ b/pumpkin/src/net/java/config.rs @@ -31,7 +31,7 @@ const BRAND_CHANNEL_PREFIX: &str = "minecraft:brand"; impl JavaClient { pub async fn handle_client_information_config( &self, - client_information: SClientInformationConfig, + client_information: SClientInformationConfig<'_>, ) { debug!("Handling client settings"); if client_information.view_distance <= 0 { @@ -47,7 +47,7 @@ impl JavaClient { ChatMode::try_from(client_information.chat_mode.0), ) { *self.config.lock().await = Some(PlayerConfig { - locale: client_information.locale, + locale: client_information.locale.to_string(), // client_information.view_distance was checked above to be > 0 so compiler should optimize this out. view_distance: NonZeroU8::new(client_information.view_distance as u8).unwrap(), chat_mode, @@ -63,11 +63,11 @@ impl JavaClient { } } - pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) { + pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage<'_>) { debug!("Handling plugin message"); if plugin_message.channel.starts_with(BRAND_CHANNEL_PREFIX) { debug!("Got a client brand"); - match str::from_utf8(&plugin_message.data) { + match str::from_utf8(plugin_message.data) { Ok(brand) => *self.brand.lock().await = Some(brand.to_string()), Err(e) => self.kick(TextComponent::text(e.to_string())).await, } @@ -144,7 +144,7 @@ impl JavaClient { self.send_known_packs().await; } - pub fn handle_config_cookie_response(&self, packet: &SConfigCookieResponse) { + pub fn handle_config_cookie_response(&self, packet: &SConfigCookieResponse<'_>) { // TODO: allow plugins to access this debug!( "Received cookie_response[config]: key: \"{}\", has_payload: \"{}\", payload_length: \"{:?}\"", diff --git a/pumpkin/src/net/java/login.rs b/pumpkin/src/net/java/login.rs index acf8c2aaf..df0778b14 100644 --- a/pumpkin/src/net/java/login.rs +++ b/pumpkin/src/net/java/login.rs @@ -288,7 +288,7 @@ impl JavaClient { Ok(profile) } - pub fn handle_login_cookie_response(&self, packet: &SLoginCookieResponse) { + pub fn handle_login_cookie_response(&self, packet: &SLoginCookieResponse<'_>) { // TODO: allow plugins to access this debug!( "Received cookie_response[login]: key: \"{}\", payload_length: \"{:?}\"", diff --git a/pumpkin/src/net/java/mod.rs b/pumpkin/src/net/java/mod.rs index 1f8a7977c..26208498e 100644 --- a/pumpkin/src/net/java/mod.rs +++ b/pumpkin/src/net/java/mod.rs @@ -267,7 +267,7 @@ impl JavaClient { // Generate a unique ID (current timestamp in ms) let keep_alive_id = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .unwrap_or_default() .as_millis() as i64; self.keep_alive_id.store(keep_alive_id); @@ -361,11 +361,14 @@ impl JavaClient { let mut buf = Vec::new(); let version = self.version.load(); - buf.write_var_int(&VarInt(CChunkData::to_id(version))) - .unwrap(); - CChunkData(chunk) - .write_packet_data(&mut buf, &version) - .unwrap(); + if let Err(err) = buf.write_var_int(&VarInt(CChunkData::to_id(version))) { + error!("Failed to write chunk data id: {err:?}"); + continue; + } + if let Err(err) = CChunkData(chunk).write_packet_data(&mut buf, &version) { + error!("Failed to write chunk data: {err:?}"); + continue; + } self.send_packet_now_data(buf.into()).await; } self.send_packet_now(&CChunkBatchEnd::new(chunks.len() as u16)) @@ -375,7 +378,10 @@ impl JavaClient { pub async fn enqueue_packet(&self, packet: &P) { let mut buf = Vec::new(); let writer = &mut buf; - self.write_packet(packet, writer).unwrap(); + if let Err(err) = self.write_packet(packet, writer) { + error!("Failed to write packet: {err:?}"); + return; + } let payload = Bytes::from(buf); let player = self.player.lock().await.clone(); @@ -395,7 +401,10 @@ impl JavaClient { pub fn try_enqueue_packet(&self, packet: &P) { let mut buf = Vec::new(); let writer = &mut buf; - self.write_packet(packet, writer).unwrap(); + if let Err(err) = self.write_packet(packet, writer) { + error!("Failed to write packet: {err:?}"); + return; + } self.try_enqueue_packet_data(buf.into()); } @@ -495,7 +504,10 @@ impl JavaClient { pub async fn send_packet_now(&self, packet: &P) { let mut packet_buf = Vec::new(); let writer = &mut packet_buf; - self.write_packet(packet, writer).unwrap(); + if let Err(err) = self.write_packet(packet, writer) { + error!("Failed to write packet: {err:?}"); + return; + } let payload = Bytes::from(packet_buf); let player = self.player.lock().await.clone(); @@ -620,10 +632,10 @@ impl JavaClient { packet: &RawPacket, ) -> Result, ReadingError> { debug!("Handling handshake group"); - let payload = &packet.payload[..]; + let mut payload = &packet.payload[..]; match packet.id { 0 => { - self.handle_handshake(SHandShake::read(payload, &self.version.load())?) + self.handle_handshake(SHandShake::read(&mut payload, &self.version.load())?) .await; Ok(None) } @@ -640,7 +652,7 @@ impl JavaClient { packet: &RawPacket, ) -> Result, ReadingError> { debug!("Handling status group"); - let payload = &packet.payload[..]; + let mut payload = &packet.payload[..]; let version = self.version.load(); match packet.id { @@ -649,7 +661,7 @@ impl JavaClient { Ok(None) } id if id == SStatusPingRequest::to_id(version) => { - self.handle_ping_request(SStatusPingRequest::read(payload, &version)?) + self.handle_ping_request(SStatusPingRequest::read(&mut payload, &version)?) .await; Ok(None) } @@ -766,30 +778,36 @@ impl JavaClient { packet: &RawPacket, ) -> Result, ReadingError> { debug!("Handling login group for id"); - let payload = &packet.payload[..]; + let mut payload = &packet.payload[..]; let version = self.version.load(); match packet.id { id if id == SLoginStart::to_id(version) => { - self.handle_login_start(server, SLoginStart::read(payload, &version)?) + self.handle_login_start(server, SLoginStart::read(&mut payload, &version)?) .await; } id if id == SEncryptionResponse::to_id(version) => { self.handle_encryption_response( server, - SEncryptionResponse::read(payload, &version)?, + SEncryptionResponse::read(&mut payload, &version)?, ) .await; } id if id == SLoginPluginResponse::to_id(version) => { - self.handle_plugin_response(server, SLoginPluginResponse::read(payload, &version)?) - .await; + self.handle_plugin_response( + server, + SLoginPluginResponse::read(&mut payload, &version)?, + ) + .await; } id if id == SLoginAcknowledged::to_id(version) => { self.handle_login_acknowledged(server).await; } id if id == SLoginCookieResponse::to_id(version) => { - self.handle_login_cookie_response(&SLoginCookieResponse::read(payload, &version)?); + self.handle_login_cookie_response(&SLoginCookieResponse::read( + &mut payload, + &version, + )?); } _ => { error!( @@ -807,25 +825,27 @@ impl JavaClient { packet: &RawPacket, ) -> Result, ReadingError> { debug!("Handling config group for id {}", packet.id); - let payload = &packet.payload[..]; + let mut payload = &packet.payload[..]; let version = self.version.load(); match packet.id { id if id == SClientInformationConfig::to_id(version) => { self.handle_client_information_config(SClientInformationConfig::read( - payload, &version, + &mut payload, + &version, )?) .await; } id if id == SPluginMessage::to_id(version) => { - self.handle_plugin_message(SPluginMessage::read(payload, &version)?) + self.handle_plugin_message(SPluginMessage::read(&mut payload, &version)?) .await; } id if id == pumpkin_protocol::java::server::config::SCustomClickAction::to_id(version) => { let _packet = pumpkin_protocol::java::server::config::SCustomClickAction::read( - payload, &version, + &mut payload, + &version, )?; warn!("CustomClickAction in config state not yet supported"); } @@ -834,7 +854,7 @@ impl JavaClient { } id if id == SKnownPacks::to_id(version) => { if let Some(i) = self - .handle_known_packs(SKnownPacks::read(payload, &version)?, server) + .handle_known_packs(SKnownPacks::read(&mut payload, &version)?, server) .await { return Ok(Some(i)); @@ -842,19 +862,23 @@ impl JavaClient { } id if id == pumpkin_protocol::java::server::config::SKeepAlive::to_id(version) => { self.handle_config_keep_alive( - pumpkin_protocol::java::server::config::SKeepAlive::read(payload, &version)?, + pumpkin_protocol::java::server::config::SKeepAlive::read( + &mut payload, + &version, + )?, ) .await; } id if id == SConfigCookieResponse::to_id(version) => { self.handle_config_cookie_response(&SConfigCookieResponse::read( - payload, &version, + &mut payload, + &version, )?); } id if id == SConfigResourcePack::to_id(version) => { self.handle_resource_pack_response( server, - SConfigResourcePack::read(payload, &version)?, + SConfigResourcePack::read(&mut payload, &version)?, ) .await; } @@ -875,7 +899,7 @@ impl JavaClient { server: &Arc, packet: &RawPacket, ) -> Result<(), Box> { - let payload = &packet.payload[..]; + let mut payload = &packet.payload[..]; let version = self.version.load(); let mut event = crate::plugin::server::packet::PacketReceivedEvent::new( @@ -890,63 +914,81 @@ impl JavaClient { match packet.id { id if id == SConfirmTeleport::to_id(version) => { - self.handle_confirm_teleport(player, SConfirmTeleport::read(payload, &version)?) - .await; + self.handle_confirm_teleport( + player, + SConfirmTeleport::read(&mut payload, &version)?, + ) + .await; } id if id == SChangeGameMode::to_id(version) => { - self.handle_change_game_mode(player, SChangeGameMode::read(payload, &version)?) - .await; + self.handle_change_game_mode( + player, + SChangeGameMode::read(&mut payload, &version)?, + ) + .await; } id if id == SChatCommand::to_id(version) => { - self.handle_chat_command(player, server, &(SChatCommand::read(payload, &version)?)) - .await; + self.handle_chat_command( + player, + server, + &(SChatCommand::read(&mut payload, &version)?), + ) + .await; } id if id == SChatMessage::to_id(version) => { - self.handle_chat_message(server, player, SChatMessage::read(payload, &version)?) - .await; + self.handle_chat_message( + server, + player, + SChatMessage::read(&mut payload, &version)?, + ) + .await; } id if id == SClientInformationPlay::to_id(version) => { self.handle_client_information( player, - SClientInformationPlay::read(payload, &version)?, + SClientInformationPlay::read(&mut payload, &version)?, ) .await; } id if id == SClientCommand::to_id(version) => { - self.handle_client_status(player, SClientCommand::read(payload, &version)?) + self.handle_client_status(player, SClientCommand::read(&mut payload, &version)?) .await; } id if id == SPlayerInput::to_id(version) => { - self.handle_player_input(player, SPlayerInput::read(payload, &version)?, server) - .await; + self.handle_player_input( + player, + SPlayerInput::read(&mut payload, &version)?, + server, + ) + .await; } id if id == SMoveVehicle::to_id(version) => { - self.handle_move_vehicle(player, SMoveVehicle::read(payload, &version)?) + self.handle_move_vehicle(player, SMoveVehicle::read(&mut payload, &version)?) .await; } id if id == SPaddleBoat::to_id(version) => { - self.handle_paddle_boat(player, SPaddleBoat::read(payload, &version)?) + self.handle_paddle_boat(player, SPaddleBoat::read(&mut payload, &version)?) .await; } id if id == SInteract::to_id(version) => { - self.handle_interact(player, SInteract::read(payload, &version)?, server) + self.handle_interact(player, SInteract::read(&mut payload, &version)?, server) .await; } id if id == SBundleItemSelected::to_id(version) => { self.handle_bundle_item_selected( player, - SBundleItemSelected::read(payload, &version)?, + SBundleItemSelected::read(&mut payload, &version)?, ) .await; } id if id == SAttack::to_id(version) => { - self.handle_attack(player, SAttack::read(payload, &version)?, server) + self.handle_attack(player, SAttack::read(&mut payload, &version)?, server) .await; } id if id == STeleportToEntity::to_id(version) => { self.handle_teleport_to_entity( player, - STeleportToEntity::read(payload, &version)?, + STeleportToEntity::read(&mut payload, &version)?, server, ) .await; @@ -954,7 +996,7 @@ impl JavaClient { id if id == pumpkin_protocol::java::server::play::SKeepAlive::to_id(version) => { self.handle_keep_alive( player, - pumpkin_protocol::java::server::play::SKeepAlive::read(payload, &version)?, + pumpkin_protocol::java::server::play::SKeepAlive::read(&mut payload, &version)?, ) .await; } @@ -964,35 +1006,39 @@ impl JavaClient { id if id == STestInstanceBlockAction::to_id(version) => { self.handle_test_instance_block_action( player, - &STestInstanceBlockAction::read(payload, &version)?, + &STestInstanceBlockAction::read(&mut payload, &version)?, ); } id if id == SSetTestBlock::to_id(version) => { - self.handle_set_test_block(player, &SSetTestBlock::read(payload, &version)?); + self.handle_set_test_block(player, &SSetTestBlock::read(&mut payload, &version)?); } id if id == SPlayerPosition::to_id(version) => { - self.handle_position(player, server, SPlayerPosition::read(payload, &version)?) - .await; + self.handle_position( + player, + server, + SPlayerPosition::read(&mut payload, &version)?, + ) + .await; } id if id == SPlayerPositionRotation::to_id(version) => { self.handle_position_rotation( player, server, - SPlayerPositionRotation::read(payload, &version)?, + SPlayerPositionRotation::read(&mut payload, &version)?, ) .await; } id if id == SPlayerRotation::to_id(version) => { - self.handle_rotation(player, SPlayerRotation::read(payload, &version)?) + self.handle_rotation(player, SPlayerRotation::read(&mut payload, &version)?) .await; } id if id == SSetPlayerGround::to_id(version) => { - self.handle_player_ground(player, &SSetPlayerGround::read(payload, &version)?); + self.handle_player_ground(player, &SSetPlayerGround::read(&mut payload, &version)?); } id if id == SPickItemFromBlock::to_id(version) => { self.handle_pick_item_from_block( player, - SPickItemFromBlock::read(payload, &version)?, + SPickItemFromBlock::read(&mut payload, &version)?, ) .await; } @@ -1002,7 +1048,8 @@ impl JavaClient { self.handle_pick_item_from_entity( player, pumpkin_protocol::java::server::play::SPickItemFromEntity::read( - payload, &version, + &mut payload, + &version, )?, ) .await; @@ -1010,31 +1057,41 @@ impl JavaClient { id if id == SPlayerAbilities::to_id(version) => { self.handle_player_abilities( player, - SPlayerAbilities::read(payload, &version)?, + SPlayerAbilities::read(&mut payload, &version)?, server, ) .await; } id if id == SPlayerAction::to_id(version) => { - self.handle_player_action(player, SPlayerAction::read(payload, &version)?, server) - .await; + self.handle_player_action( + player, + SPlayerAction::read(&mut payload, &version)?, + server, + ) + .await; } id if id == SSetCommandBlock::to_id(version) => { - self.handle_set_command_block(player, SSetCommandBlock::read(payload, &version)?) - .await; + self.handle_set_command_block( + player, + SSetCommandBlock::read(&mut payload, &version)?, + ) + .await; } id if id == SSetJigsawBlock::to_id(version) => { - self.handle_set_jigsaw_block(player, SSetJigsawBlock::read(payload, &version)?) - .await; + self.handle_set_jigsaw_block( + player, + SSetJigsawBlock::read(&mut payload, &version)?, + ) + .await; } id if id == SJigsawGenerate::to_id(version) => { - self.handle_jigsaw_generate(player, SJigsawGenerate::read(payload, &version)?) + self.handle_jigsaw_generate(player, SJigsawGenerate::read(&mut payload, &version)?) .await; } id if id == SPlayerCommand::to_id(version) => { self.handle_player_command( player, - SPlayerCommand::read(payload, &version)?, + SPlayerCommand::read(&mut payload, &version)?, server, ) .await; @@ -1043,126 +1100,133 @@ impl JavaClient { Self::handle_player_loaded(player); } id if id == SPlayPingRequest::to_id(version) => { - self.handle_play_ping_request(SPlayPingRequest::read(payload, &version)?) + self.handle_play_ping_request(SPlayPingRequest::read(&mut payload, &version)?) .await; } id if id == SClickSlot::to_id(version) => { player - .on_slot_click(SClickSlot::read(payload, &version)?, server) + .on_slot_click(SClickSlot::read(&mut payload, &version)?, server) .await; } id if id == SContainerButtonClick::to_id(version) => { player - .on_container_button_click(SContainerButtonClick::read(payload, &version)?) + .on_container_button_click(SContainerButtonClick::read(&mut payload, &version)?) .await; } id if id == SSetHeldItem::to_id(version) => { - self.handle_set_held_item(player, SSetHeldItem::read(payload, &version)?) + self.handle_set_held_item(player, SSetHeldItem::read(&mut payload, &version)?) .await; } id if id == SSetCreativeSlot::to_id(version) => { - self.handle_set_creative_slot(player, SSetCreativeSlot::read(payload, &version)?) - .await?; + self.handle_set_creative_slot( + player, + SSetCreativeSlot::read(&mut payload, &version)?, + ) + .await?; } id if id == SSwingArm::to_id(version) => { - self.handle_swing_arm(player, SSwingArm::read(payload, &version)?) + self.handle_swing_arm(player, SSwingArm::read(&mut payload, &version)?) .await; } id if id == SUpdateSign::to_id(version) => { - self.handle_sign_update(player, SUpdateSign::read(payload, &version)?) + self.handle_sign_update(player, SUpdateSign::read(&mut payload, &version)?) .await; } id if id == SUseItemOn::to_id(version) => { - self.handle_use_item_on(player, SUseItemOn::read(payload, &version)?, server) + self.handle_use_item_on(player, SUseItemOn::read(&mut payload, &version)?, server) .await?; } id if id == SUseItem::to_id(version) => { - self.handle_use_item(player, &SUseItem::read(payload, &version)?, server) + self.handle_use_item(player, &SUseItem::read(&mut payload, &version)?, server) .await; } id if id == SCommandSuggestion::to_id(version) => { self.handle_command_suggestion( player, - SCommandSuggestion::read(payload, &version)?, + SCommandSuggestion::read(&mut payload, &version)?, server, ) .await; } id if id == SPCookieResponse::to_id(version) => { - self.handle_cookie_response(&SPCookieResponse::read(payload, &version)?); + self.handle_cookie_response(&SPCookieResponse::read(&mut payload, &version)?); } id if id == SCloseContainer::to_id(version) => { self.handle_close_container( player, server, - SCloseContainer::read(payload, &version)?, + SCloseContainer::read(&mut payload, &version)?, ) .await; } id if id == SChunkBatch::to_id(version) => { - self.handle_chunk_batch(player, SChunkBatch::read(payload, &version)?) + self.handle_chunk_batch(player, SChunkBatch::read(&mut payload, &version)?) .await; } id if id == SPlayerSession::to_id(version) => { self.handle_chat_session_update( player, server, - SPlayerSession::read(payload, &version)?, + SPlayerSession::read(&mut payload, &version)?, ) .await; } id if id == SCustomPayload::to_id(version) => { - let payload = SCustomPayload::read(payload, &version)?; + let payload = SCustomPayload::read(&mut payload, &version)?; let event = PlayerCustomPayloadEvent::new( player.clone(), payload.channel.to_string(), - Bytes::from(payload.data), + Bytes::copy_from_slice(payload.data), ); server.plugin_manager.fire(event).await; } id if id == SRecipeBookChangeSettings::to_id(version) => { self.handle_recipe_book_change_settings( player, - SRecipeBookChangeSettings::read(payload, &version)?, + SRecipeBookChangeSettings::read(&mut payload, &version)?, ) .await; } id if id == SRecipeBookSeenRecipe::to_id(version) => { self.handle_recipe_book_seen_recipe( player, - SRecipeBookSeenRecipe::read(payload, &version)?, + SRecipeBookSeenRecipe::read(&mut payload, &version)?, ) .await; } id if id == SRenameItem::to_id(version) => { player - .on_rename_item(SRenameItem::read(payload, &version)?) + .on_rename_item(SRenameItem::read(&mut payload, &version)?) .await; } id if id == SPlaceRecipe::to_id(version) => { - let packet = SPlaceRecipe::read(payload, &version)?; + let packet = SPlaceRecipe::read(&mut payload, &version)?; self.handle_place_recipe(server, player, packet).await; } id if id == pumpkin_protocol::java::server::play::SCustomClickAction::to_id(version) => { let packet = pumpkin_protocol::java::server::play::SCustomClickAction::read( - payload, &version, + &mut payload, + &version, )?; let event = crate::plugin::api::events::player::custom_click_action::CustomClickActionEvent::new( player.clone(), - packet.action_id.clone(), - packet.payload.map(Bytes::from), + packet.action_id.to_string(), + packet.payload.map(Bytes::copy_from_slice), ); server.plugin_manager.fire(event).await; } id if id == SSelectTrade::to_id(version) => { - self.handle_select_trade(player, SSelectTrade::read(payload, &version)?) + self.handle_select_trade(player, SSelectTrade::read(&mut payload, &version)?) .await; } id if id == SSeenAdvancement::to_id(version) => { - self.handle_seen_advancement(player, SSeenAdvancement::read(payload, &version)?) - .await; + self.handle_seen_advancement( + player, + SSeenAdvancement::read(&mut payload, &version)?, + ) + .await; } _ => { warn!("Failed to handle player packet id {}", packet.id); diff --git a/pumpkin/src/net/java/play.rs b/pumpkin/src/net/java/play.rs index 73095f621..86609af77 100644 --- a/pumpkin/src/net/java/play.rs +++ b/pumpkin/src/net/java/play.rs @@ -677,7 +677,7 @@ impl JavaClient { &self, player: &Arc, server: &Arc, - command: &SChatCommand, + command: &SChatCommand<'_>, ) { player.update_last_action_time(); let player_clone = player.clone(); @@ -686,7 +686,7 @@ impl JavaClient { server; PlayerCommandSendEvent { player: player.clone(), - command: command.command.clone(), + command: command.command.to_string(), cancelled: false }; @@ -739,7 +739,10 @@ impl JavaClient { return; } - let stack = ItemStack::new(1, Item::from_id(block.item_id).unwrap()); + let Some(item) = Item::from_id(block.item_id) else { + return; + }; + let stack = ItemStack::new(1, item); let slot_with_stack = player.inventory().get_slot_with_stack(&stack).await; @@ -802,8 +805,8 @@ impl JavaClient { } } - if let Some(egg_item_id) = found_egg { - let stack = ItemStack::new(1, Item::from_id(egg_item_id).unwrap()); + if let Some(item) = found_egg.and_then(Item::from_id) { + let stack = ItemStack::new(1, item); let slot_with_stack = player.inventory().get_slot_with_stack(&stack).await; @@ -838,7 +841,7 @@ impl JavaClient { pub async fn handle_set_command_block( &self, player: &Arc, - mut command: SSetCommandBlock, + command: SSetCommandBlock<'_>, ) { if !player.is_creative() { return; @@ -869,8 +872,11 @@ impl JavaClient { CommandBlockMode::Impulse => Block::COMMAND_BLOCK, }; - let old_command_block: &CommandBlockEntity = - block_entity.as_any().downcast_ref().unwrap(); + let Some(old_command_block) = + block_entity.as_any().downcast_ref::() + else { + return; + }; props.conditional = command.flags & 0x2 != 0; @@ -884,8 +890,9 @@ impl JavaClient { ) .await; - if command.command.starts_with('/') { - command.command.remove(0); + let mut cmd = command.command; + if cmd.starts_with('/') { + cmd = &cmd[1..]; } let command_block = CommandBlockEntity { @@ -897,7 +904,7 @@ impl JavaClient { .into(), auto: (command.flags & 0x4 != 0).into(), dirty: old_command_block.dirty.load(Ordering::SeqCst).into(), - command: Mutex::new(command.command.clone()), + command: Mutex::new(cmd.to_string()), last_output: old_command_block.last_output.lock().await.clone().into(), track_output: (command.flags & 0x1 != 0).into(), success_count: AtomicU32::new(0), @@ -923,7 +930,7 @@ impl JavaClient { } } - pub async fn handle_set_jigsaw_block(&self, player: &Arc, jigsaw: SSetJigsawBlock) { + pub async fn handle_set_jigsaw_block(&self, player: &Arc, jigsaw: SSetJigsawBlock<'_>) { if !player.is_creative() { return; } @@ -937,13 +944,16 @@ impl JavaClient { return; } - let jigsaw_block: &JigsawBlockEntity = block_entity.as_any().downcast_ref().unwrap(); + let Some(jigsaw_block) = block_entity.as_any().downcast_ref::() + else { + return; + }; - *jigsaw_block.name.lock().await = jigsaw.name; - *jigsaw_block.target.lock().await = jigsaw.target; - *jigsaw_block.pool.lock().await = jigsaw.pool; - *jigsaw_block.final_state.lock().await = jigsaw.final_state; - *jigsaw_block.joint.lock().await = JigsawJointType::from_str(&jigsaw.joint); + *jigsaw_block.name.lock().await = jigsaw.name.to_string(); + *jigsaw_block.target.lock().await = jigsaw.target.to_string(); + *jigsaw_block.pool.lock().await = jigsaw.pool.to_string(); + *jigsaw_block.final_state.lock().await = jigsaw.final_state.to_string(); + *jigsaw_block.joint.lock().await = JigsawJointType::from_str(jigsaw.joint); jigsaw_block .selection_priority .store(jigsaw.selection_priority.0, Ordering::SeqCst); @@ -1368,7 +1378,9 @@ impl JavaClient { PlayerInteractEvent::new(player, InteractAction::LeftClickAir, &Block::AIR, None) }; - let server = player.world().server.upgrade().unwrap(); + let Some(server) = player.world().server.upgrade() else { + return; + }; send_cancellable! {{ server; @@ -1383,7 +1395,7 @@ impl JavaClient { &self, server: &Server, player: &Arc, - chat_message: SChatMessage, + chat_message: SChatMessage<'_>, ) { player.update_last_action_time(); let gameprofile = &player.gameprofile; @@ -1451,7 +1463,7 @@ impl JavaClient { &self, server: &Server, player: &Arc, - chat_message: &SChatMessage, + chat_message: &SChatMessage<'_>, ) -> Result<(), ChatError> { // Check for oversized messages // If we're able to find the 257th UTF-16 character, the message is too big. @@ -1598,7 +1610,7 @@ impl JavaClient { pub async fn handle_client_information( &self, player: &Arc, - client_information: SClientInformationPlay, + client_information: SClientInformationPlay<'_>, ) { if let (Ok(main_hand), Ok(chat_mode)) = ( Hand::try_from(client_information.main_hand.0), @@ -1641,7 +1653,7 @@ impl JavaClient { }; let new_config = PlayerConfig { - locale: client_information.locale, + locale: client_information.locale.to_string(), view_distance: new_view_distance, chat_mode, chat_colors: client_information.chat_colors, @@ -2407,7 +2419,7 @@ impl JavaClient { BlockActionResult::Pass } - pub async fn handle_sign_update(&self, player: &Player, sign_data: SUpdateSign) { + pub async fn handle_sign_update(&self, player: &Player, sign_data: SUpdateSign<'_>) { let world = player.get_entity().world.load_full(); let Some(block_entity) = world.get_block_entity(&sign_data.location) else { return; @@ -2426,10 +2438,10 @@ impl JavaClient { }; *text.messages.lock().unwrap() = [ - sign_data.line_1, - sign_data.line_2, - sign_data.line_3, - sign_data.line_4, + sign_data.line_1.into(), + sign_data.line_2.into(), + sign_data.line_3.into(), + sign_data.line_4.into(), ]; *sign_entity.currently_editing_player.lock().await = None; world.update_block_entity(&block_entity); @@ -2735,7 +2747,7 @@ impl JavaClient { pub async fn handle_command_suggestion( &self, player: &Arc, - packet: SCommandSuggestion, + packet: SCommandSuggestion<'_>, server: &Arc, ) { let Some(cmd) = &packet.command.get(1..) else { @@ -2756,15 +2768,15 @@ impl JavaClient { let response = CCommandSuggestions::new( packet.id, - (last_word_start + 2).try_into().unwrap(), - (cmd.len() - last_word_start - 1).try_into().unwrap(), + ((last_word_start + 2) as i32).into(), + ((cmd.len() - last_word_start - 1) as i32).into(), suggestions.into(), ); self.enqueue_packet(&response).await; } - pub fn handle_cookie_response(&self, packet: &SPCookieResponse) { + pub fn handle_cookie_response(&self, packet: &SPCookieResponse<'_>) { // TODO: allow plugins to access this debug!( "Received cookie_response[play]: key: \"{}\", payload_length: \"{:?}\"", @@ -2897,7 +2909,7 @@ impl JavaClient { pub fn handle_test_instance_block_action( &self, player: &Arc, - packet: &STestInstanceBlockAction, + packet: &STestInstanceBlockAction<'_>, ) { if !player.has_client_loaded() { return; @@ -2909,7 +2921,7 @@ impl JavaClient { ); } - pub fn handle_set_test_block(&self, player: &Arc, packet: &SSetTestBlock) { + pub fn handle_set_test_block(&self, player: &Arc, packet: &SSetTestBlock<'_>) { if !player.has_client_loaded() { return; } diff --git a/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs b/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs index b15679bb5..b8b3fd2bd 100644 --- a/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs +++ b/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs @@ -740,7 +740,7 @@ pub fn serialize_java_packet( #[must_use] pub fn deserialize_java_serverbound_packet( id: i32, - payload: &[u8], + mut payload: &[u8], version: JavaMinecraftVersion, ) -> Option { match id { @@ -748,7 +748,7 @@ pub fn deserialize_java_serverbound_packet( == pumpkin_protocol::java::server::config::SClientInformationConfig::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSClientInformationConfig(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSClientInformationConfig { locale: p.locale.into(), view_distance: p.view_distance.try_into().unwrap(), @@ -762,21 +762,21 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::config::SKeepAlive::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSKeepAlive(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSKeepAlive { keep_alive_id: p.keep_alive_id.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::config::SKnownPacks::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSKnownPacks(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSKnownPacks { known_pack_count: p.known_pack_count.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::config::SConfigResourcePack::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSConfigResourcePack(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSConfigResourcePack { uuid: crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::uuid::Uuid { high: p.uuid.as_u64_pair().1, low: p.uuid.as_u64_pair().0 }, result: p.result.0.try_into().unwrap(), @@ -784,14 +784,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SAttack::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SAttack(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SAttack { entity_id: p.entity_id.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SBundleItemSelected::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SBundleItemSelected(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SBundleItemSelected { slot_id: p.slot_id.0.try_into().unwrap(), selected_item_index: p.selected_item_index.0.try_into().unwrap(), @@ -799,21 +799,21 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SChatCommand::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SChatCommand(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SChatCommand { command: p.command.into(), })) } id if id == pumpkin_protocol::java::server::play::SChunkBatch::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SChunkBatch(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SChunkBatch { chunks_per_tick: p.chunks_per_tick.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SClientCommand::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SClientCommand(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SClientCommand { action_id: p.action_id.0.try_into().unwrap(), })) @@ -822,7 +822,7 @@ pub fn deserialize_java_serverbound_packet( == pumpkin_protocol::java::server::play::SClientInformationPlay::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SClientInformationPlay(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SClientInformationPlay { locale: p.locale.into(), view_distance: p.view_distance.try_into().unwrap(), @@ -836,14 +836,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SCloseContainer::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SCloseContainer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SCloseContainer { window_id: p.window_id.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SCommandSuggestion::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SCommandSuggestion(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SCommandSuggestion { id: p.id.0.try_into().unwrap(), command: p.command.into(), @@ -851,14 +851,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SConfirmTeleport::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SConfirmTeleport(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SConfirmTeleport { teleport_id: p.teleport_id.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SContainerButtonClick::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SContainerButtonClick(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SContainerButtonClick { window_id: p.window_id.0.try_into().unwrap(), button_id: p.button_id.0.try_into().unwrap(), @@ -866,7 +866,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SJigsawGenerate::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SJigsawGenerate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SJigsawGenerate { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), levels: p.levels.0.try_into().unwrap(), @@ -875,14 +875,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SKeepAlive::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SKeepAlive(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SKeepAlive { keep_alive_id: p.keep_alive_id.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SMoveVehicle::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SMoveVehicle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SMoveVehicle { x: p.x.try_into().unwrap(), y: p.y.try_into().unwrap(), @@ -893,7 +893,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPaddleBoat::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPaddleBoat(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPaddleBoat { left_paddle: p.left_paddle.try_into().unwrap(), right_paddle: p.right_paddle.try_into().unwrap(), @@ -901,7 +901,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPickItemFromBlock::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPickItemFromBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPickItemFromBlock { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), include_data: p.include_data.try_into().unwrap(), @@ -909,7 +909,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPickItemFromEntity::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPickItemFromEntity(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPickItemFromEntity { id: p.id.0, include_data: p.include_data.try_into().unwrap(), @@ -917,14 +917,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPlayPingRequest::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayPingRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayPingRequest { payload: p.payload.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SPlaceRecipe::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlaceRecipe(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlaceRecipe { container_id: p.container_id.try_into().unwrap(), recipe_display_id: p.recipe_display_id.0.try_into().unwrap(), @@ -933,14 +933,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPlayerAbilities::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerAbilities(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerAbilities { flags: p.flags.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerAction::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerAction(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerAction { status: p.status.0.try_into().unwrap(), position: (p.position.0.x, p.position.0.y, p.position.0.z), @@ -950,21 +950,21 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SSetPlayerGround::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetPlayerGround(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetPlayerGround { on_ground: p.on_ground.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerInput::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerInput(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerInput { input: p.input.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerPosition::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerPosition { position: (p.position.x as _, p.position.y as _, p.position.z as _), collision: p.collision.try_into().unwrap(), @@ -974,7 +974,7 @@ pub fn deserialize_java_serverbound_packet( == pumpkin_protocol::java::server::play::SPlayerPositionRotation::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerPositionRotation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerPositionRotation { position: (p.position.x as _, p.position.y as _, p.position.z as _), yaw: p.yaw.try_into().unwrap(), @@ -984,7 +984,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SPlayerRotation::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerRotation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerRotation { yaw: p.yaw.try_into().unwrap(), pitch: p.pitch.try_into().unwrap(), @@ -995,7 +995,7 @@ pub fn deserialize_java_serverbound_packet( == pumpkin_protocol::java::server::play::SRecipeBookChangeSettings::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SRecipeBookChangeSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SRecipeBookChangeSettings { book_type: p.book_type.0.try_into().unwrap(), is_open: p.is_open.try_into().unwrap(), @@ -1004,21 +1004,21 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SRecipeBookSeenRecipe::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SRecipeBookSeenRecipe(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SRecipeBookSeenRecipe { recipe_display_id: p.recipe_display_id.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SRenameItem::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SRenameItem(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SRenameItem { item_name: p.item_name.into(), })) } id if id == pumpkin_protocol::java::server::play::SSeenAdvancement::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(match p { pumpkin_protocol::java::server::play::SSeenAdvancement::OpenTab(identifier) => ServerboundPacket::SSeenAdvancement(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSeenAdvancement::OpenTab(identifier.to_string())), pumpkin_protocol::java::server::play::SSeenAdvancement::CloseTab => ServerboundPacket::SSeenAdvancement(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSeenAdvancement::CloseTab), @@ -1026,14 +1026,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SSelectTrade::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSelectTrade(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSelectTrade { selected_slot: p.selected_slot.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SSetCommandBlock::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetCommandBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetCommandBlock { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), command: p.command.into(), @@ -1043,14 +1043,14 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SSetHeldItem::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetHeldItem(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetHeldItem { slot: p.slot.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::SSetJigsawBlock::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetJigsawBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetJigsawBlock { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), name: p.name.into(), @@ -1064,21 +1064,21 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SSwingArm::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSwingArm(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSwingArm { hand: p.hand.0.try_into().unwrap(), })) } id if id == pumpkin_protocol::java::server::play::STeleportToEntity::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::STeleportToEntity(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::STeleportToEntity { target: crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::uuid::Uuid { high: p.target.as_u64_pair().1, low: p.target.as_u64_pair().0 }, })) } id if id == pumpkin_protocol::java::server::play::SUseItem::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SUseItem(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUseItem { hand: p.hand.0.try_into().unwrap(), sequence: p.sequence.0.try_into().unwrap(), @@ -1088,7 +1088,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::play::SUseItemOn::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SUseItemOn(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUseItemOn { hand: p.hand.0.try_into().unwrap(), position: (p.position.0.x, p.position.0.y, p.position.0.z), @@ -1101,7 +1101,7 @@ pub fn deserialize_java_serverbound_packet( } id if id == pumpkin_protocol::java::server::status::SStatusPingRequest::to_id(version) => { use pumpkin_protocol::ServerPacket; - let p = ::read(&mut Cursor::new(payload), &version).ok()?; + let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::StatusSStatusPingRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::StatusSStatusPingRequest { payload: p.payload.try_into().unwrap(), })) diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index ecd4f12ea..3d63841eb 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -550,7 +550,7 @@ impl World { self.broadcast_editioned(&je_packet, &be_packet).await; } - fn component_to_bedrock_text(message: &TextComponent) -> SText { + fn component_to_bedrock_text(message: &TextComponent) -> SText<'static> { match &*message.0.content { pumpkin_util::text::TextContent::Translate { translate, @@ -612,7 +612,7 @@ impl World { pub async fn broadcast_secure_player_chat( &self, sender: &Arc, - chat_message: &SChatMessage, + chat_message: &SChatMessage<'_>, decorated_message: &TextComponent, ) { let messages_sent: i32 = sender.chat_session.lock().await.messages_sent; @@ -627,8 +627,8 @@ impl World { VarInt(messages_received), sender.gameprofile.id, VarInt(messages_sent), - chat_message.signature.clone(), - chat_message.message.clone(), + chat_message.signature.map(std::convert::Into::into), + chat_message.message.into(), chat_message.timestamp, chat_message.salt, sender_last_seen.indexed_for(recipient).await, @@ -640,11 +640,13 @@ impl World { ); recipient.client.enqueue_packet(packet).await; - recipient - .signature_cache - .lock() - .await - .add_seen_signature(&chat_message.signature.clone().unwrap()); // Unwrap is safe because we check for None in validate_chat_message + if let Some(signature) = chat_message.signature { + recipient + .signature_cache + .lock() + .await + .add_seen_signature(signature); + } if recipient.gameprofile.id != sender.gameprofile.id { // Sender may update recipient on signatures recipient hasn't seen @@ -2545,7 +2547,7 @@ impl World { .send_packet_now(&CLogin::new( entity_id, base_config.hardcore, - dimensions, + &dimensions, server .advanced_config .networking