From 89f554ed36c8c1ac8876d9921a21c7ec7335f749 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sun, 23 Aug 2026 16:22:01 +0200 Subject: [PATCH] chore: add release ci --- .github/workflows/release.yml | 139 +++++++++ .github/workflows/rust.yml | 31 +- Cargo.lock | 276 +++++++++--------- Cargo.toml | 6 +- crates/pumpkin-nbt/fuzz/Cargo.lock | 4 +- crates/pumpkin-plugin-api/src/lib.rs | 6 +- crates/pumpkin-protocol/fuzz/Cargo.lock | 7 +- .../src/java/client/play/spawn_entity.rs | 2 + crates/pumpkin-util/src/gamemode.rs | 28 ++ crates/pumpkin/Cargo.toml | 4 +- .../argument_types/entity_selector/mod.rs | 8 +- .../argument_types/entity_selector/parser.rs | 7 +- .../pumpkin/src/command/commands/teleport.rs | 12 +- crates/pumpkin/src/command/node/dispatcher.rs | 14 +- crates/pumpkin/src/command/snbt/rules.rs | 9 +- .../src/command/suggestion/suggestions.rs | 36 ++- crates/pumpkin/src/entity/hunger.rs | 2 +- crates/pumpkin/src/entity/living.rs | 14 +- crates/pumpkin/src/entity/player.rs | 233 +++++++++++---- .../src/entity/projectile/eye_of_ender.rs | 31 ++ .../src/net/java/login/encryption_response.rs | 2 +- .../src/plugin/loader/wasm/wasm_host/mod.rs | 12 +- .../plugin/loader/wasm/wasm_host/signature.rs | 6 +- crates/pumpkin/src/world/mod.rs | 2 +- tools/pumpkin-codegen/Cargo.toml | 2 +- 25 files changed, 596 insertions(+), 297 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..1517f51bc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,139 @@ +name: Release + +on: + push: + tags: + - "*" + - "!nightly" + - "!nightly*" + workflow_dispatch: + inputs: + tag_name: + description: "Release Tag name (optional, defaults to Cargo.toml version)" + required: false + type: string + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-Dwarnings" + +jobs: + build_release: + name: Build & Sign Release + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + [ + ubuntu-latest, + ubuntu-26.04-arm, + windows-latest, + windows-11-arm, + macos-latest, + ] + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - uses: Swatinem/rust-cache@v2 + + - name: Build Release + shell: bash + run: | + cargo build --verbose --release + + - name: Prepare artifacts + shell: bash + run: | + mkdir -p dist + if [ "${{ runner.os }}" == "Windows" ]; then EXT=".exe"; fi + cp "target/release/pumpkin$EXT" "dist/pumpkin-${{ runner.arch }}-${{ runner.os }}$EXT" + + - name: Upload unsigned executable for SignPath (Windows only) + if: runner.os == 'Windows' + id: upload_unsigned + uses: actions/upload-artifact@v7 + with: + name: unsigned-${{ runner.arch }}-${{ runner.os }} + path: dist/pumpkin-* + retention-days: 1 + + - name: Submit SignPath signing request (Windows only) + if: runner.os == 'Windows' + uses: signpath/github-action-submit-signing-request@v2 + with: + api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' + organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}' + project-slug: '${{ secrets.SIGNPATH_PROJECT_SLUG }}' + signing-policy-slug: '${{ secrets.SIGNPATH_RELEASE_SIGNING_POLICY_SLUG || secrets.SIGNPATH_SIGNING_POLICY_SLUG }}' + github-artifact-id: '${{ steps.upload_unsigned.outputs.artifact-id }}' + wait-for-completion: true + output-artifact-directory: dist/signed/ + + - name: Overwrite with signed version (Windows only) + if: runner.os == 'Windows' + shell: bash + run: | + cp dist/signed/* dist/ + rm -rf dist/signed/ + + - name: Export executable + uses: actions/upload-artifact@v7 + with: + name: pumpkin-${{ runner.arch }}-${{ runner.os }} + compression-level: 9 + path: dist/pumpkin-* + + publish_release: + name: Publish GitHub Release + permissions: + contents: write + needs: [build_release] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Determine tag name + id: tag + shell: bash + run: | + if [ -n "${{ github.event.inputs.tag_name }}" ]; then + TAG="${{ github.event.inputs.tag_name }}" + elif [ "${{ github.ref_type }}" == "tag" ]; then + TAG="${{ github.ref_name }}" + else + VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml) + TAG="${VERSION}" + fi + echo "tag_name=${TAG}" >> $GITHUB_OUTPUT + echo "Determined release tag: ${TAG}" + + - name: Download prebuilt binary artifacts + uses: actions/download-artifact@v8 + with: + pattern: "pumpkin-*" + path: dist/ + merge-multiple: true + + - name: Generate Checksums + shell: bash + run: | + cd dist + sha256sum pumpkin-* > checksums.sha256 + cat checksums.sha256 + + - name: Create GitHub Release + uses: softprops/action-gh-release@v3 + with: + tag_name: ${{ steps.tag.outputs.tag_name }} + name: Release ${{ steps.tag.outputs.tag_name }} + files: | + dist/pumpkin* + dist/checksums.sha256 + generate_release_notes: true diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e69648c8b..9cf3b29d5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -109,7 +109,7 @@ jobs: os: [ ubuntu-latest, - ubuntu-24.04-arm, + ubuntu-26.04-arm, windows-latest, windows-11-arm, macos-latest, @@ -135,35 +135,6 @@ jobs: mkdir -p dist if [ "${{ runner.os }}" == "Windows" ]; then EXT=".exe"; fi cp "target/release/pumpkin$EXT" "dist/pumpkin-${{ runner.arch }}-${{ runner.os }}$EXT" - - - name: Upload unsigned executable for SignPath (Windows only) - if: runner.os == 'Windows' && github.event_name == 'push' && github.ref == 'refs/heads/master' - id: upload_unsigned - uses: actions/upload-artifact@v7 - with: - name: unsigned-${{ runner.arch }}-${{ runner.os }} - path: dist/pumpkin-* - retention-days: 1 - - - name: Submit SignPath signing request (Windows only) - if: runner.os == 'Windows' && github.event_name == 'push' && github.ref == 'refs/heads/master' - uses: signpath/github-action-submit-signing-request@v2 - with: - api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' - organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}' - project-slug: '${{ secrets.SIGNPATH_PROJECT_SLUG }}' - signing-policy-slug: '${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}' - github-artifact-id: '${{ steps.upload_unsigned.outputs.artifact-id }}' - wait-for-completion: true - output-artifact-directory: dist/signed/ - - - name: Overwrite with signed version (Windows only) - if: runner.os == 'Windows' && github.event_name == 'push' && github.ref == 'refs/heads/master' - shell: bash - run: | - cp dist/signed/* dist/ - rm -rf dist/signed/ - - name: Export executable uses: actions/upload-artifact@v7 with: diff --git a/Cargo.lock b/Cargo.lock index 99e8d3463..46c45a858 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -487,9 +487,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cap-fs-ext" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78e5a3368ae89b7cb68186411452b4b9fac8b41be9c19bf3f47c2d2c8e36e6b" +checksum = "56ff379b70af8e08307a8f65e7040c7301cb4a572538ade16b4984f0da77847f" dependencies = [ "cap-primitives", "cap-std", @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "cap-primitives" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdadbd7c002d3a484b35243669abdae85a0ebaded5a61117169dc3400f9a7ff0" +checksum = "8b5f74729fd2f44701d1a8eb47e906cdb3ccd9ec0f02baad85a744b791940b18" dependencies = [ "ambient-authority", "fs-set-times", @@ -517,9 +517,9 @@ dependencies = [ [[package]] name = "cap-std" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7281235d6e96d3544ca18bba9049be92f4190f8d923e3caef1b5f66cfa752608" +checksum = "c1ec78e242cfa2cfe276807ac2ecc00315a6c97786977414bcd1c3963b6c91b8" dependencies = [ "cap-primitives", "io-extras", @@ -544,9 +544,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -896,27 +896,27 @@ dependencies = [ [[package]] name = "cranelift-assembler-x64" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d552bd33b7a56dc70aeb1e1c960e51a218fa0db50f23873b500a310379450b2d" +checksum = "16c273ba1bfc3a1cb27cb4f83df27134f3cb638a61f5ed79ab22cf86eb13da0d" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078e80e4c222279e3330f6aa1a256ca77ddf156d4453166a9f09defedc4594dd" +checksum = "cbf8909326a466739e83ffe11e74c0c8c6b4bfa911b612aece915daa746cff58" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "820ce15d4ad3562d613c31a67b6d0434d403e7091a68d1349903842f7d31737e" +checksum = "3cb26b06b54d8b2f8cdf4d440a32fc3b3b91c71c162333a69a70a66fa265fc45" dependencies = [ "cranelift-entity", "wasmtime-internal-core", @@ -924,9 +924,9 @@ dependencies = [ [[package]] name = "cranelift-bitset" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61bca563d4b86d285928d9e27f97f27039bb33a0fc524fa130d7d0c106bf8ab3" +checksum = "7ce4e57dbb7f73d08011808a19787c3a03c3e7854b2a479ed0b788915fb671be" dependencies = [ "serde", "serde_derive", @@ -935,9 +935,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709f4b7c0fb57d952658d5b5c07fbdc4149acd7b7f0de9678ae754b9c981949a" +checksum = "74b0a8968f33d0bc13bc86fe70dd3947e93acc9f358ed9848e9988448972a9be" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -966,9 +966,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903dc8915af62aad1d9d0f39a5968d33fa80b9aa899ed6f56e47f40ca4512e1e" +checksum = "f69e8e2fe9deb48ef7b8d0c61612f8c1e2277d0421c201e30a4c844a4ebac698" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -979,24 +979,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0522d74c227e49f3fd49ab055311486ae4f09083262b66705bed676952491469" +checksum = "ad4db1e87a65e9c5a832e3ede160830d4e34df938ac38b5604819f8825687e73" [[package]] name = "cranelift-control" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66560ea1c5cef72e170b18e46d263dba2d3169c9d39e8cafdab2173c6362cc1a" +checksum = "9248cd37bb6ec460981f57ead368e32b1eca7a207ad50e3e9c7adc3b161f20e9" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ef5b17cc814d27e96b66a5b46da0e4ce2b8ac55a6d478048bb99d04b05526" +checksum = "26b8bc91c0a3530d132acbf118965dabe9a084029eb0fa74b64760360dec3316" dependencies = [ "cranelift-bitset", "serde", @@ -1006,9 +1006,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a87e0aaa39dbf70693b348a221e45904111704ee8f9fef140498471005f9842d" +checksum = "5086f2ebc084a98b387e522680f62ef65a512444d8382151e03088716d3a1714" dependencies = [ "cranelift-codegen", "hashbrown 0.17.1", @@ -1019,15 +1019,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf79003ebfa1eed5e87f3b84446ad5236f540268289960e14f387dc9b28e40b7" +checksum = "b6a658670f779afc2df083be201ebe54805f69b7b9ffa8dab04142b72ed751c9" [[package]] name = "cranelift-native" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05bf4f235743c81e67ee4db617c5a4a0b65d58d3f0cfc575ee0f1a4e0cd58273" +checksum = "16a41083b1fd953debd6f32d21fcda765b258f323ce907fdd6b4715f2769c478" dependencies = [ "cranelift-codegen", "libc", @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.134.3" +version = "0.134.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6977c2a71ab1e0d1e62f966b411a498aa04c4dce47d93d52f8a360a06058922" +checksum = "244d9cd0759b0a3ccdd587cafb13434f9ea43b5c9d07701d277daf5cd0f7b7c1" [[package]] name = "crc" @@ -1076,9 +1076,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" dependencies = [ "cfg-if", ] @@ -1518,9 +1518,9 @@ dependencies = [ [[package]] name = "either" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" @@ -1898,9 +1898,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.15" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +checksum = "839c0e8a181239723652be9062bb56ca5bf5f64011f73b623f6f4fc59086a228" dependencies = [ "atomic-waker", "bytes", @@ -2211,9 +2211,9 @@ checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92a7ed671a6aad807a8651a2e1782a6598fda9ce5185dd8158549e95a91c6428" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -2495,9 +2495,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "lz4-java-wrc" @@ -2862,9 +2862,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "ordered-float" -version = "5.3.0" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +checksum = "c860fd3227ca4ac3cc032e2cd20cba3f02ccdf4b610538f8ee6584d56bb62e96" dependencies = [ "num-traits", ] @@ -3294,9 +3294,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5c8c21ea032e4efbdf2d067dc45171779dbe0c8ecf20ef4a57efa7474f2b0a" +checksum = "ed2bd641cb6a3ec5bffe60405568933163e0ea619da0943e9d2a417ceaa7fe82" dependencies = [ "cranelift-bitset", "log", @@ -3306,9 +3306,9 @@ dependencies = [ [[package]] name = "pulley-macros" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f10925455d5dde962e3604eade797ba5488644c8ee14a44191e2f2b58980574" +checksum = "d3fd4024d1e559eaf5579bc8ad84a2b5915f34b47acc13a06ffba7dac401b166" dependencies = [ "proc-macro2", "quote", @@ -3374,8 +3374,8 @@ dependencies = [ "tracing-subscriber", "ureq", "uuid", - "wasm-encoder 0.256.0", - "wasmparser 0.256.0", + "wasm-encoder 0.257.1", + "wasmparser 0.257.1", "wasmtime", "wasmtime-wasi", "wasmtime-wasi-http", @@ -3868,9 +3868,9 @@ dependencies = [ [[package]] name = "rtc" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f294ac22b05a087786d41f2fc90d8e2ac29523ed80f341137471a639ae4a653b" +checksum = "e55da8e478486106f04db1ccba177ae3260fb12899982cd5cddf2ac0e1cdcfe9" dependencies = [ "bytes", "hex", @@ -3903,9 +3903,9 @@ dependencies = [ [[package]] name = "rtc-datachannel" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627b03b91a689584ee412b50775ec3661ceae695f64643d30fd0cd7bcacf75f" +checksum = "7bef39b017b5cf0a3511eab456505556b320e0aa04d4547b015ecba9f844fe43" dependencies = [ "bytes", "log", @@ -3916,9 +3916,9 @@ dependencies = [ [[package]] name = "rtc-dtls" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa4c6505bfaac8c577a476468527aa4b2d2186dc01ddf42a3154e4b093db63b" +checksum = "03a1be8a58a72a257c233ad9a2f92130c15994e02f7a1981379fdebbe0d8761a" dependencies = [ "aes 0.8.4", "bytecheck", @@ -3949,9 +3949,9 @@ dependencies = [ [[package]] name = "rtc-ice" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e1e5aa8ea2da99de35403d5cfe030597010a4041bf8f79a5760797f31adf12" +checksum = "640c7ecb9a09d21c0d4ba27b3ff22adb07cce90d23a7bce7c82bcbe424844e31" dependencies = [ "bytes", "crc", @@ -3968,9 +3968,9 @@ dependencies = [ [[package]] name = "rtc-interceptor" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66ea5650a91773d10e4d98729f6fe256681ec1314c7ded5839fa34867305f79" +checksum = "9436633af4a6beff6fee08c99464012017fcd1e0a4c0559b1f0d733e8812217a" dependencies = [ "log", "rand", @@ -3983,9 +3983,9 @@ dependencies = [ [[package]] name = "rtc-interceptor-derive" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb131530a31fd0c2981b29ab589e6e1e7bab00cbd0c38e5be0f3e70409c4656" +checksum = "3563dafffb11e99264cbfa87c45d806c349c701a96ea3cf3c4778ae3c5da63b4" dependencies = [ "proc-macro2", "quote", @@ -3994,9 +3994,9 @@ dependencies = [ [[package]] name = "rtc-mdns" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6ca18a03372550e3c6f2074528b82e6ff1f4379c9b4aa954ffd4122832dded" +checksum = "e4db343dbcd1445783ac9f832e350775e4e655b2c890bead7d13dca1219e0ac5" dependencies = [ "bytes", "log", @@ -4007,9 +4007,9 @@ dependencies = [ [[package]] name = "rtc-media" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbc2f460a321eccdc0907819f8fc7027036edcbd94620c3328c1aefb070dfe5" +checksum = "709a571ed5d88854f3f8c0b92e4a445d77ee54fd33dd45f9297a3d91e3e96d67" dependencies = [ "byteorder", "bytes", @@ -4021,9 +4021,9 @@ dependencies = [ [[package]] name = "rtc-rtcp" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b363d36dd1d37f2d744ae6303322a4f3ea472fba8d37922fdab68f5ffca3e0" +checksum = "8817201df4a87008528804073d2dddfefd08eecb44afe6f6d61f7fb1beed72d0" dependencies = [ "bytes", "rtc-shared", @@ -4031,9 +4031,9 @@ dependencies = [ [[package]] name = "rtc-rtp" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac1a05add837d45d562f48bc769c9b264440741aab319fed48ce6a696e6aa0c" +checksum = "b2aa84012c4a3d855586878e9f891af5062bd5690278b2c54bfcfb0a0ddd9098" dependencies = [ "bytes", "memchr", @@ -4044,9 +4044,9 @@ dependencies = [ [[package]] name = "rtc-sctp" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0024399d881c2900f2ee65fa6d7ed08a11abde24c5b3bcbf008a6dec5ff93124" +checksum = "78317cf685b6cde3dbd1cd8e7c9f373e74f00dce00000a25c14c6ddb3378da86" dependencies = [ "bytes", "crc32c", @@ -4060,9 +4060,9 @@ dependencies = [ [[package]] name = "rtc-sdp" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0379bb552d4813e042d376db99f2005038017fc7864676fc835334b810db015" +checksum = "54ab04410496c8ea47350490298fb135f5432f8fa1aa88edf5dadc81c855a324" dependencies = [ "rand", "rtc-shared", @@ -4071,9 +4071,9 @@ dependencies = [ [[package]] name = "rtc-shared" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f292c11ce7d5311629c9c5ad0aa8a031441b22ac0f6bcf9891848d98b686703" +checksum = "dae32667b8c9f15223172ce27471e02791e2b401de559b3ea02a6ec93ff280e0" dependencies = [ "aes 0.8.4", "aes-gcm", @@ -4093,9 +4093,9 @@ dependencies = [ [[package]] name = "rtc-srtp" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f12dc0499de1a0e5fcb70035fcb424e014ae63787090367c458bb4e0989e30f" +checksum = "413d48daef797c98c12ff91988abac36d44c81974f0a4b0658549174230819cd" dependencies = [ "aes 0.8.4", "byteorder", @@ -4112,9 +4112,9 @@ dependencies = [ [[package]] name = "rtc-stun" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b8dc1e1fa7f52721766440968af9e994f2e373c46b5da60744877ca3714e77" +checksum = "e4b4540b2b8ff7155ef9e95a3b492a7830e974e2fa9ce4b76ec315c4a6b4953d" dependencies = [ "base64 0.22.1", "bytes", @@ -4131,9 +4131,9 @@ dependencies = [ [[package]] name = "rtc-turn" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40f85fcf7475cde6d7aaab4c2655761ddcf84bb427bbb15b99b2de85cb524ce0" +checksum = "449365ff0b87488d5f9532409813e76e1f0f5965ef31ce6fcde9aa786c852c6c" dependencies = [ "bytes", "log", @@ -4231,9 +4231,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.14" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "ring", "rustls-pki-types", @@ -5193,9 +5193,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.24.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -5308,12 +5308,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.256.0" +version = "0.257.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1492381bfd5ea51c2a99a919b676662559925cb8d7490547ec2e14c1ad3eb1" +checksum = "7d8ad9f0a39050867bda22e6486c316e2e52d20a42154d5bc433934bf738d085" dependencies = [ "leb128fmt", - "wasmparser 0.256.0", + "wasmparser 0.257.1", ] [[package]] @@ -5355,15 +5355,13 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.256.0" +version = "0.257.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60bd825ffedc6cba8a642924ba7ae424afbc47811cffbcb7b92031ec24e59b4c" +checksum = "d92fc335fb6d48f46bda1d8b26b69e28320c15ac3272208333833d6e217e2b4a" dependencies = [ "bitflags 2.13.1", - "hashbrown 0.17.1", "indexmap", "semver", - "serde", ] [[package]] @@ -5379,9 +5377,9 @@ dependencies = [ [[package]] name = "wasmtime" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80ca6098e0d4d06886d91d7f2cc3cb6623eb583c4c0ab3c89cbfb6098c8586c" +checksum = "4cdaf5b8af5713146e3a62d940c71e3eb2ad1ebacfa6b55f0c8509a5b4b87718" dependencies = [ "addr2line", "async-trait", @@ -5423,9 +5421,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134f9d136d29c76f6c1b4c9b468e97a2efc38c7d49fd188e39b64870b2fea701" +checksum = "58793271eab7ec26bab99ca497131f8b37702e7dc39e2f2d18293e3e915b4964" dependencies = [ "anyhow", "cpp_demangle", @@ -5454,9 +5452,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-cache" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65db2eb1bfc5371a3b4107dbf539d0b93d05016fc29625b1648146b47db02071" +checksum = "ede02ba77442cab88a2ddd5d16373e8bc450b55e05de8be039b024987a53d5a7" dependencies = [ "base64 0.22.1", "directories-next", @@ -5474,9 +5472,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-component-macro" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf7b91fed3fc34781d57f9c6654ea2513bf0a99f7b0b0523c00de1e6efebe1c" +checksum = "c5bba4eff4804620bae04d7793308d97a0c5a8a97ea19e635452518f84560f84" dependencies = [ "anyhow", "proc-macro2", @@ -5489,15 +5487,15 @@ dependencies = [ [[package]] name = "wasmtime-internal-component-util" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc8a678149885cae00289f806fbe74c7863084cf74cace0b8dc73602279400e1" +checksum = "3d7032ff6b4d7a45e05be1cb32ec1756df5f2669f08296dbe2c61c3789dead2c" [[package]] name = "wasmtime-internal-core" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0092c4b9d070ac5e278b6d0db10f5e71214190f0347ca57502b4692f796321" +checksum = "f41d3b2cb9c3de7b696690af070d408b5e357011832f8b8bb7fbb315dbb620ed" dependencies = [ "hashbrown 0.17.1", "libm", @@ -5506,9 +5504,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-cranelift" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6851ebc9e03cab23d9821d2b2505d380bdfe38f35ccec945247b05274d85c98b" +checksum = "1d5cda5b90247978dd2ba6ca4e309508da19e9244445671d2d0e6a34e5c3b847" dependencies = [ "cfg-if", "cranelift-codegen", @@ -5533,9 +5531,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-fiber" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b26da6d5f60d4c438da70bba3553fe810a840533a64156be287dca2081c6991" +checksum = "4d126366176553e8f304e8ac2078a4cc37134fe8f19d4d4695a09c5a2f577f10" dependencies = [ "cc", "cfg-if", @@ -5548,9 +5546,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-debug" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed621ba25d7bf78b7edd7b4749abbb27c2e5cdba836c9504a424ee74b6c23149" +checksum = "c1d28ff131bc40e11d84bc3a9fa0d264506439ffbbc89f3562fbb529d1caa617" dependencies = [ "cc", "wasmtime-internal-versioned-export-macros", @@ -5558,9 +5556,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5684ba160951baad06a725696f3c590e2fb0e8067c2aebee27bf7f9259058e85" +checksum = "4a52de8b6afbfcd618073f592c1450cb661574e7061f3f4a44f1f7ec0c7f7909" dependencies = [ "cfg-if", "libc", @@ -5570,9 +5568,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-unwinder" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112eead527bffa8ff0646a11fb4339a9d52ddd1da2b9a6fce4aff84c815dd94f" +checksum = "5524fbaaf3d2134dd6229164d7fc81e443cce06d1e0576524d5f4e86e747cb13" dependencies = [ "cfg-if", "cranelift-codegen", @@ -5583,9 +5581,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-versioned-export-macros" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "153592e0bed824fc13c6696203fa1bd7bd20eb355316475e39a55f081ef80eca" +checksum = "e93bb9ae112a80618510f938275a5d88637b656e7d0a021fc906f52206c708ad" dependencies = [ "proc-macro2", "quote", @@ -5594,9 +5592,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-wit-bindgen" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c456ad6e81e0f46abfeca43687d18ea15e289c395b262ea6e0023e2682e088be" +checksum = "bfdbdd9d6fab1ecb67a7dc189e32c9e341444945fb709437bf8aab25d9a88459" dependencies = [ "anyhow", "bitflags 2.13.1", @@ -5607,9 +5605,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1cf60cd6a565213af7074b4aad7bb5e110e3c6c6aae54425aa0500a0e15e86" +checksum = "b373095a6dc8382da56882ad16d7ea16771dd6927dd480b1ce3fe7c4b816d2cf" dependencies = [ "async-trait", "bitflags 2.13.1", @@ -5632,9 +5630,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi-http" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a499879061ee9f724342d5f5009754b723ae53c7932161ee063a9fe19395e915" +checksum = "372fc7845f26cd8f69bcbf6e4234fcc032f718480c7722fa20a28eb74d58998e" dependencies = [ "async-trait", "bytes", @@ -5656,9 +5654,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi-io" -version = "47.0.3" +version = "47.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb08e1d7755aaa467ce14080b7b01e33c914a920f6000696f1e42e40ea6387e" +checksum = "51b3c9b39b1a1b3029f80e614623e182f165133dfaca8610f156450343f080a4" dependencies = [ "async-trait", "bytes", @@ -5678,9 +5676,9 @@ dependencies = [ [[package]] name = "webrtc" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "116da0f0e617d01d91872ece8fdef0da42dfb39747b2fe48760ae544b52f2344" +checksum = "7330857e1e10fcbfa5f358f152cc01f22a05bb523875c0547677db0f24538dcd" dependencies = [ "async-broadcast", "async-channel", @@ -6094,15 +6092,15 @@ dependencies = [ [[package]] name = "wit-encoder" -version = "0.256.0" +version = "0.257.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8085a1e724fa8c48f9f5489b9d8f121eb9fc2554ebcdaf6936256d854b24390" +checksum = "5e819ad1dda8dcc9fa0958b54b6b6b46e52159ff9572228fa957dba8c74d3e69" dependencies = [ "id-arena", "pretty_assertions", "semver", "serde", - "wit-parser 0.256.0", + "wit-parser 0.257.1", ] [[package]] @@ -6145,9 +6143,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.256.0" +version = "0.257.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa073dadefba859cb03f689a0c2e3efc51f883bf86b907eaa9709bfd9e3a00a9" +checksum = "6f815340f0bb65d9775ae21e56b503b496683557b9b627b195d2766c25fb24ae" dependencies = [ "anyhow", "hashbrown 0.17.1", @@ -6159,7 +6157,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-ident", - "wasmparser 0.256.0", + "wasmparser 0.257.1", ] [[package]] @@ -6345,9 +6343,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b5c6b5976d66c1d703c4fd17d3f5e43c8cedaacf604961b171adc7130896d8" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -6356,9 +6354,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47402523226a02bfe5230160dc3ccc089aa6f6f19e7fcbb4e6f824bbb1b4aa62" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 815ea9306..d234a3a90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,7 +135,7 @@ futures = { version = "0.3", default-features = false, features = ["executor"] } rayon = { version = "1.12", default-features = false } crossbeam = { version = "0.8", default-features = false, features = ["std"] } -uuid = { version = "1.24", default-features = false, features = ["serde", "v3", "v4", "std"] } +uuid = { version = "1.25", default-features = false, features = ["serde", "v3", "v4", "std"] } serde = { version = "1.0", default-features = false, features = ["derive", "std"] } serde_repr = { version = "0.1", default-features = false } serde_json = { version = "1.0", default-features = false, features = ["std"] } @@ -213,7 +213,7 @@ notify = { version = "8.2.0", default-features = false, features = ["macos_fseve sysinfo = { version = "0.39", default-features = false, features = ["system"] } rustc_version_runtime = { version = "0.3", default-features = false } -ordered-float = { version = "5.3", default-features = false, features = ["std"] } +ordered-float = { version = "5.4", default-features = false, features = ["std"] } xxhash-rust = { version = "0.8", default-features = false, features = ["xxh64"] } wasmtime = { version = "47.0", default-features = false, features = ["runtime", "component-model", "async", "cache", "cranelift", "gc", "gc-drc", "threads", "std"] } @@ -222,7 +222,7 @@ wasmtime-wasi-http = { version = "47.0", default-features = false, features = [" # needed for interacting with wasmtime-wasi-http - keep in sync hyper = { version = "^1.11", default-features = false } axum = { version = "0.8.9", default-features = false, features = ["http1", "tokio"] } -webrtc = { version = "0.20.2" } +webrtc = { version = "0.20.3" } async-trait = "0.1" wit-bindgen = { version = "0.60", default-features = false, features = ["macros"] } diff --git a/crates/pumpkin-nbt/fuzz/Cargo.lock b/crates/pumpkin-nbt/fuzz/Cargo.lock index b81aca2bd..0f87521a3 100644 --- a/crates/pumpkin-nbt/fuzz/Cargo.lock +++ b/crates/pumpkin-nbt/fuzz/Cargo.lock @@ -458,9 +458,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "uuid" -version = "1.24.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ "getrandom 0.4.3", "js-sys", diff --git a/crates/pumpkin-plugin-api/src/lib.rs b/crates/pumpkin-plugin-api/src/lib.rs index 49a1afe87..210f20e7a 100644 --- a/crates/pumpkin-plugin-api/src/lib.rs +++ b/crates/pumpkin-plugin-api/src/lib.rs @@ -420,9 +420,11 @@ pub fn register_plugin(build_plugin: fn() -> Box) { /// If called before [`register_plugin`] has initialized `PLUGIN`. fn plugin() -> &'static mut dyn Plugin { #[expect(static_mut_refs)] - #[allow(clippy::unwrap_used)] + #[allow(clippy::expect_used)] unsafe { - PLUGIN.as_deref_mut().unwrap() + PLUGIN + .as_deref_mut() + .expect("PLUGIN must be initialized with register_plugin before use") } } diff --git a/crates/pumpkin-protocol/fuzz/Cargo.lock b/crates/pumpkin-protocol/fuzz/Cargo.lock index c6a1d21aa..ddc32a5e7 100644 --- a/crates/pumpkin-protocol/fuzz/Cargo.lock +++ b/crates/pumpkin-protocol/fuzz/Cargo.lock @@ -1179,6 +1179,7 @@ dependencies = [ "pumpkin-util", "pumpkin-world", "serde", + "serde_json", "thiserror", "tokio", "uuid", @@ -1203,6 +1204,7 @@ dependencies = [ "bytes", "colored", "crypto-bigint", + "dashmap", "ecdsa", "md5", "num-derive", @@ -1215,7 +1217,6 @@ dependencies = [ "serde_json", "sha2", "thiserror", - "tokio", "ureq", "uuid", ] @@ -1835,9 +1836,9 @@ checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" [[package]] name = "uuid" -version = "1.24.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ "getrandom 0.4.2", "js-sys", diff --git a/crates/pumpkin-protocol/src/java/client/play/spawn_entity.rs b/crates/pumpkin-protocol/src/java/client/play/spawn_entity.rs index 7eefadeab..f3a61c044 100644 --- a/crates/pumpkin-protocol/src/java/client/play/spawn_entity.rs +++ b/crates/pumpkin-protocol/src/java/client/play/spawn_entity.rs @@ -301,6 +301,8 @@ impl ClientPacket for CSpawnEntity { data = VarInt(5); } else if self.r#type.0 == i32::from(EntityType::COMMAND_BLOCK_MINECART.id) { data = VarInt(6); + } else if self.r#type.0 == i32::from(EntityType::ITEM.id) { + data = VarInt(1); } } diff --git a/crates/pumpkin-util/src/gamemode.rs b/crates/pumpkin-util/src/gamemode.rs index 83daefbcf..7f251b796 100644 --- a/crates/pumpkin-util/src/gamemode.rs +++ b/crates/pumpkin-util/src/gamemode.rs @@ -75,6 +75,34 @@ impl TryFrom for GameMode { } } +impl TryFrom for GameMode { + type Error = (); + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Self::Survival), + 1 => Ok(Self::Creative), + 2 => Ok(Self::Adventure), + 3 => Ok(Self::Spectator), + _ => Err(()), + } + } +} + +impl TryFrom for GameMode { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::Survival), + 1 => Ok(Self::Creative), + 2 => Ok(Self::Adventure), + 3 => Ok(Self::Spectator), + _ => Err(()), + } + } +} + impl FromStr for GameMode { type Err = ParseGameModeError; diff --git a/crates/pumpkin/Cargo.toml b/crates/pumpkin/Cargo.toml index ccda31dfb..cacc7cc91 100644 --- a/crates/pumpkin/Cargo.toml +++ b/crates/pumpkin/Cargo.toml @@ -72,8 +72,8 @@ rsa.workspace = true # verification & WASM parsing ed25519-dalek.workspace = true hex.workspace = true -wasmparser = "0.256" -wasm-encoder = "0.256" +wasmparser.workspace = true +wasm-encoder = "0.257" # authentication ureq = { workspace = true, features = ["json"] } diff --git a/crates/pumpkin/src/command/argument_types/entity_selector/mod.rs b/crates/pumpkin/src/command/argument_types/entity_selector/mod.rs index 505449e17..ce2fca552 100644 --- a/crates/pumpkin/src/command/argument_types/entity_selector/mod.rs +++ b/crates/pumpkin/src/command/argument_types/entity_selector/mod.rs @@ -165,12 +165,10 @@ impl EntitySelector { &self, source: &CommandSource, ) -> Result, CommandSyntaxError> { - let list = self.find_players(source).await?; + let mut list = self.find_players(source).await?; if list.len() == 1 { - Ok(list - .first() - .expect("List length is 1, so first should exist") - .clone()) + list.pop() + .ok_or_else(|| entity::NO_PLAYERS_ERROR_TYPE.create_without_context()) } else { Err(entity::NO_PLAYERS_ERROR_TYPE.create_without_context()) } diff --git a/crates/pumpkin/src/command/argument_types/entity_selector/parser.rs b/crates/pumpkin/src/command/argument_types/entity_selector/parser.rs index 1cfde6a31..0cf40ddc8 100644 --- a/crates/pumpkin/src/command/argument_types/entity_selector/parser.rs +++ b/crates/pumpkin/src/command/argument_types/entity_selector/parser.rs @@ -246,11 +246,10 @@ impl<'b, 'a> EntitySelectorParser<'b, 'a> { fn parse_selector(&mut self) -> Result<(), CommandSyntaxError> { self.uses_selector_variable = true; self.suggestions = EntitySelectorParserSuggestions::Selector; - if !self.reader.can_read_char() { - return Err(MISSING_SELECTOR_TYPE_ERROR_TYPE.create(self.reader)); - } let i = self.reader.cursor(); - let char = self.reader.read().expect("can_read_char is true"); + let Some(char) = self.reader.read() else { + return Err(MISSING_SELECTOR_TYPE_ERROR_TYPE.create(self.reader)); + }; let mut add_alive_predicate = false; match char { 'a' => { diff --git a/crates/pumpkin/src/command/commands/teleport.rs b/crates/pumpkin/src/command/commands/teleport.rs index 6d78cb933..fb3eb21ae 100644 --- a/crates/pumpkin/src/command/commands/teleport.rs +++ b/crates/pumpkin/src/command/commands/teleport.rs @@ -58,10 +58,10 @@ fn yaw_pitch_facing_position( fn resolve_sender_world( sender: &CommandSender, server: &crate::server::Server, -) -> std::sync::Arc { +) -> Result, CommandError> { sender .world_or_first(server) - .expect("Server should have at least one world") + .ok_or(CommandError::InvalidRequirement) } async fn success_key_and_arg( @@ -149,7 +149,7 @@ impl CommandExecutor for EntitiesToPosFacingPosExecutor { } let facing_pos = Position3DArgumentConsumer::find_arg(args, ARG_FACING_LOCATION)?; let (yaw, pitch) = yaw_pitch_facing_position(&pos, &facing_pos); - let world = resolve_sender_world(sender, server); + let world = resolve_sender_world(sender, server)?; for target in targets { target @@ -205,7 +205,7 @@ impl CommandExecutor for EntitiesToPosFacingEntityExecutor { let facing_entity = EntityArgumentConsumer::find_arg(args, ARG_FACING_ENTITY)?; let (yaw, pitch) = yaw_pitch_facing_position(&pos, &facing_entity.get_entity().pos.load()); - let world = resolve_sender_world(sender, server); + let world = resolve_sender_world(sender, server)?; for target in targets { target @@ -261,7 +261,7 @@ impl CommandExecutor for EntitiesToPosWithRotationExecutor { // Note: Rotation returns (yaw, is_yaw_relative, pitch, is_pitch_relative) // For teleport, we use absolute values only (ignore relative flags) let (yaw, _, pitch, _) = RotationArgumentConsumer::find_arg(args, ARG_ROTATION)?; - let world = resolve_sender_world(sender, server); + let world = resolve_sender_world(sender, server)?; for target in targets { target @@ -314,7 +314,7 @@ impl CommandExecutor for EntitiesToPosExecutor { [], ))); } - let world = resolve_sender_world(sender, server); + let world = resolve_sender_world(sender, server)?; for target in targets { let yaw = target.get_entity().yaw.load(); let pitch = target.get_entity().pitch.load(); diff --git a/crates/pumpkin/src/command/node/dispatcher.rs b/crates/pumpkin/src/command/node/dispatcher.rs index 76717e770..93a8c46c0 100644 --- a/crates/pumpkin/src/command/node/dispatcher.rs +++ b/crates/pumpkin/src/command/node/dispatcher.rs @@ -352,13 +352,8 @@ impl CommandDispatcher { /// Executes a given result that has already been parsed from an input. pub async fn execute(&self, parsed: ParsingResult<'_>) -> Result { if parsed.reader.peek().is_some() { - return if parsed.errors.len() == 1 { - Err(parsed - .errors - .values() - .next() - .expect("Errors length is 1, so next should exist") - .clone()) + return if let Some(err) = parsed.errors.values().next() { + Err(err.clone()) } else if parsed.context.range.is_empty() { Err(DISPATCHER_UNKNOWN_COMMAND.create(&parsed.reader)) } else { @@ -1076,10 +1071,7 @@ impl CommandDispatcher { } } if child_usages.len() == 1 { - let mut child_usage = child_usages - .into_iter() - .next() - .expect("Child usages length is 1, so next should exist"); + let mut child_usage = child_usages.pop().unwrap_or_default(); if is_optional { child_usage = format!( "{USAGE_OPTIONAL_OPEN}{child_usage}{USAGE_OPTIONAL_CLOSE}" diff --git a/crates/pumpkin/src/command/snbt/rules.rs b/crates/pumpkin/src/command/snbt/rules.rs index 363f45cfd..045fc2dc5 100644 --- a/crates/pumpkin/src/command/snbt/rules.rs +++ b/crates/pumpkin/src/command/snbt/rules.rs @@ -522,16 +522,13 @@ impl SnbtParser<'_, '_> { Some('\'') => Some(EscapeSequenceBranch::Return('\'')), Some('"') => Some(EscapeSequenceBranch::Return('"')), Some('x') => Some(EscapeSequenceBranch::CheckValidity( - u32::from_str_radix(&self.string_hex_2()?, 16) - .expect("Hexadecimal parsed should have been valid"), + u32::from_str_radix(&self.string_hex_2()?, 16).ok()?, )), Some('u') => Some(EscapeSequenceBranch::CheckValidity( - u32::from_str_radix(&self.string_hex_4()?, 16) - .expect("Hexadecimal parsed should have been valid"), + u32::from_str_radix(&self.string_hex_4()?, 16).ok()?, )), Some('U') => Some(EscapeSequenceBranch::CheckValidity( - u32::from_str_radix(&self.string_hex_8()?, 16) - .expect("Hexadecimal parsed should have been valid"), + u32::from_str_radix(&self.string_hex_8()?, 16).ok()?, )), Some('N') => { if self.reader.peek() != Some('{') { diff --git a/crates/pumpkin/src/command/suggestion/suggestions.rs b/crates/pumpkin/src/command/suggestion/suggestions.rs index b1856ae84..aa8a76264 100644 --- a/crates/pumpkin/src/command/suggestion/suggestions.rs +++ b/crates/pumpkin/src/command/suggestion/suggestions.rs @@ -412,27 +412,25 @@ impl Suggestions { match side { PushSide::Text => { - let text = text_iter.next().expect( - "text_iter should have a next value because side is PushSide::Text", - ); - suggestions.push(Suggestion { - text: SuggestionText::Text(text.0), - tooltip: text.1, - range: text.2, - }); + if let Some(text) = text_iter.next() { + suggestions.push(Suggestion { + text: SuggestionText::Text(text.0), + tooltip: text.1, + range: text.2, + }); + } } PushSide::Integer => { - let text = integer_iter.next().expect( - "integer_iter should have a next value because side is PushSide::Integer", - ); - suggestions.push(Suggestion { - text: SuggestionText::Integer { - cached_text: text.0, - value: text.1, - }, - tooltip: text.2, - range: text.3, - }); + if let Some(text) = integer_iter.next() { + suggestions.push(Suggestion { + text: SuggestionText::Integer { + cached_text: text.0, + value: text.1, + }, + tooltip: text.2, + range: text.3, + }); + } } PushSide::Break => break, } diff --git a/crates/pumpkin/src/entity/hunger.rs b/crates/pumpkin/src/entity/hunger.rs index 635d38316..d41e142af 100644 --- a/crates/pumpkin/src/entity/hunger.rs +++ b/crates/pumpkin/src/entity/hunger.rs @@ -185,7 +185,7 @@ impl NBTStorage for HungerManager { }) } - fn read_nbt<'a>(&'a mut self, nbt: &'a mut NbtCompound) -> NbtFuture<'a, ()> { + fn read_nbt_non_mut<'a>(&'a self, nbt: &'a NbtCompound) -> NbtFuture<'a, ()> { Box::pin(async move { self.level .store(nbt.get_int("foodLevel").unwrap_or(20) as u8); diff --git a/crates/pumpkin/src/entity/living.rs b/crates/pumpkin/src/entity/living.rs index 40f920b5d..8722e4b57 100644 --- a/crates/pumpkin/src/entity/living.rs +++ b/crates/pumpkin/src/entity/living.rs @@ -2234,6 +2234,9 @@ impl LivingEntity { // Persist current absorption amount nbt.put("AbsorptionAmount", NbtTag::Float(self.absorption.load())); nbt.put("FallDistance", NbtTag::Float(fall_distance)); + nbt.put_short("HurtTime", self.hurt_cooldown.load(Relaxed).max(0) as i16); + nbt.put_short("DeathTime", i16::from(self.death_time.load(Relaxed))); + nbt.put_bool("FallFlying", self.entity.is_fall_flying()); { let effects = self.active_effects.lock().await; if !effects.is_empty() { @@ -2254,7 +2257,7 @@ impl LivingEntity { pub fn read_living_nbt_non_mut<'a>(&'a self, nbt: &'a NbtCompound) -> NbtFuture<'a, ()> { Box::pin(async { - self.health.store(nbt.get_float("Health").unwrap_or(0.0)); + self.health.store(nbt.get_float("Health").unwrap_or(20.0)); // Clamp any persisted absorption to the entity's configured max let raw_abs = nbt.get_float("AbsorptionAmount").unwrap_or(0.0); @@ -2273,6 +2276,15 @@ impl LivingEntity { } else { self.fall_distance.store(fd); } + if let Some(hurt_time) = nbt.get_short("HurtTime") { + self.hurt_cooldown.store(i32::from(hurt_time), Relaxed); + } + if let Some(death_time) = nbt.get_short("DeathTime") { + self.death_time.store(death_time as u8, Relaxed); + } + self.entity + .fall_flying + .store(nbt.get_bool("FallFlying").unwrap_or(false), Relaxed); { let mut active_effects = self.active_effects.lock().await; let nbt_effects = nbt.get_list("active_effects"); diff --git a/crates/pumpkin/src/entity/player.rs b/crates/pumpkin/src/entity/player.rs index 3ec7d63cb..2703bef55 100644 --- a/crates/pumpkin/src/entity/player.rs +++ b/crates/pumpkin/src/entity/player.rs @@ -798,6 +798,9 @@ pub struct Player { pub enchantment_seed: AtomicI32, pub fishing_bobber: AtomicI32, pub bedrock_skin: arc_swap::ArcSwap, + pub seen_credits: AtomicBool, + pub score: AtomicI32, + pub spawn_extra_particles_on_fall: AtomicBool, } use base64::prelude::*; @@ -1063,6 +1066,9 @@ impl Player { hidden_players: Mutex::new(std::collections::HashSet::new()), fishing_bobber: AtomicI32::new(-1), bedrock_skin: ArcSwap::new(Arc::new(bedrock_skin)), + seen_credits: AtomicBool::new(false), + score: AtomicI32::new(0), + spawn_extra_particles_on_fall: AtomicBool::new(false), } } @@ -5617,31 +5623,38 @@ impl NBTStorage for PlayerInventory { let mut equipment_compound = NbtCompound::new(); let equipment_guard = self.entity_equipment.lock().await; - for slot in self.equipment_slots.values() { - if let Some(stack) = equipment_guard.equipment.get(slot) - && !stack.is_empty() - { + for (slot, stack) in &equipment_guard.equipment { + if !stack.is_empty() { let mut item_compound = NbtCompound::new(); stack.write_item_stack(&mut item_compound); - match slot { - EquipmentSlot::OffHand(_) => { - equipment_compound.put_compound("offhand", item_compound); - } + let vanilla_slot = match slot { EquipmentSlot::Feet(_) => { - equipment_compound.put_compound("feet", item_compound); + equipment_compound.put_compound("feet", item_compound.clone()); + Some(100i8) } EquipmentSlot::Legs(_) => { - equipment_compound.put_compound("legs", item_compound); + equipment_compound.put_compound("legs", item_compound.clone()); + Some(101i8) } EquipmentSlot::Chest(_) => { - equipment_compound.put_compound("chest", item_compound); + equipment_compound.put_compound("chest", item_compound.clone()); + Some(102i8) } EquipmentSlot::Head(_) => { - equipment_compound.put_compound("head", item_compound); + equipment_compound.put_compound("head", item_compound.clone()); + Some(103i8) } - _ => { - warn!("Invalid equipment slot for a player"); + EquipmentSlot::OffHand(_) => { + equipment_compound.put_compound("offhand", item_compound.clone()); + Some(-106i8) } + _ => None, + }; + if let Some(slot_byte) = vanilla_slot { + let mut inv_item_compound = NbtCompound::new(); + inv_item_compound.put_byte("Slot", slot_byte); + stack.write_item_stack(&mut inv_item_compound); + items.push(NbtTag::Compound(inv_item_compound)); } } } @@ -5660,7 +5673,15 @@ impl NBTStorage for PlayerInventory { if let Some(item_compound) = tag.extract_compound() && let Some(slot_byte) = item_compound.get_byte("Slot") { - let slot = slot_byte as usize; + let slot = match slot_byte { + 100 => 36, // feet + 101 => 37, // legs + 102 => 38, // chest + 103 => 39, // head + -106 => 40, // offhand + s if (0..=40).contains(&s) => s as usize, + _ => continue, + }; if let Some(item_stack) = ItemStack::read_item_stack(item_compound) { self.set_stack(slot, item_stack).await; } @@ -5903,12 +5924,23 @@ impl EntityBase for Player { let total_exp = experience::points_to_level(self.experience_level.load(Ordering::Relaxed)) + self.experience_points.load(Ordering::Relaxed); + nbt.put_float("XpP", self.experience_progress.load()); + nbt.put_int("XpLevel", self.experience_level.load(Ordering::Relaxed)); nbt.put_int("XpTotal", total_exp); - nbt.put_byte("playerGameType", self.gamemode.load() as i8); + nbt.put_int("XpSeed", self.enchantment_seed.load(Ordering::Relaxed)); + nbt.put_int("Score", self.score.load(Ordering::Relaxed)); + nbt.put_short("SleepTimer", self.sleeping_since.load().unwrap_or(0) as i16); + + nbt.put_int("playerGameType", self.gamemode.load() as i32); if let Some(previous_gamemode) = self.previous_gamemode.load() { - nbt.put_byte("previousPlayerGameType", previous_gamemode as i8); + nbt.put_int("previousPlayerGameType", previous_gamemode as i32); } + nbt.put_bool("seenCredits", self.seen_credits.load(Ordering::Relaxed)); + nbt.put_bool( + "spawn_extra_particles_on_fall", + self.spawn_extra_particles_on_fall.load(Ordering::Relaxed), + ); nbt.put_bool( "HasPlayedBefore", self.has_played_before.load(Ordering::Relaxed), @@ -5917,13 +5949,13 @@ impl EntityBase for Player { // Store food level, saturation, exhaustion, and tick timer self.hunger_manager.write_nbt(nbt).await; - nbt.put_int( - "AirSupply", - self.breath_manager - .air_supply - .load(Ordering::Relaxed) - .clamp(0, super::breath::MAX_AIR), - ); + let air_supply = self + .breath_manager + .air_supply + .load(Ordering::Relaxed) + .clamp(0, super::breath::MAX_AIR); + nbt.put_short("Air", air_supply as i16); + nbt.put_int("AirSupply", air_supply); nbt.put_int( "DrowningTick", self.breath_manager @@ -5946,8 +5978,23 @@ impl EntityBase for Player { respawn.dimension.minecraft_name.to_owned(), ); nbt.put_bool("SpawnForced", respawn.force); + + let mut respawn_compound = NbtCompound::new(); + respawn_compound + .put_string("dimension", respawn.dimension.minecraft_name.to_string()); + respawn_compound.put( + "pos", + NbtTag::IntArray(vec![ + respawn.position.0.x, + respawn.position.0.y, + respawn.position.0.z, + ]), + ); + respawn_compound.put_float("angle", respawn.yaw); + respawn_compound.put_bool("forced", respawn.force); + nbt.put_compound("respawn", respawn_compound); } - nbt.put_int("XpSeed", self.enchantment_seed.load(Ordering::Relaxed)); + let vehicle_uuid = self .living_entity .entity @@ -5964,28 +6011,84 @@ impl EntityBase for Player { }) } + #[expect(clippy::too_many_lines)] fn read_custom_nbt<'a>(&'a self, nbt: &'a NbtCompound) -> NbtFuture<'a, ()> { Box::pin(async move { self.inventory.read_nbt_non_mut(nbt).await; self.ender_chest_inventory.read_nbt_non_mut(nbt).await; - self.abilities.lock().await.read_nbt_non_mut(nbt).await; - // Load from total XP + let xp_p = nbt.get_float("XpP").unwrap_or(0.0); + let xp_level = nbt.get_int("XpLevel"); let total_exp = nbt.get_int("XpTotal").unwrap_or(0); - let (level, points) = experience::total_to_level_and_points(total_exp); - let progress = experience::progress_in_level(level, points); - self.experience_level.store(level, Ordering::Relaxed); - self.experience_progress.store(progress); - self.experience_points.store(points, Ordering::Relaxed); - self.gamemode.store( - GameMode::try_from(nbt.get_byte("playerGameType").unwrap_or(0)) - .unwrap_or(GameMode::Survival), + if let Some(level) = xp_level { + self.experience_level.store(level, Ordering::Relaxed); + self.experience_progress.store(xp_p); + let points = (xp_p * experience::points_in_level(level) as f32).round() as i32; + self.experience_points.store(points, Ordering::Relaxed); + } else { + let (level, points) = experience::total_to_level_and_points(total_exp); + let progress = experience::progress_in_level(level, points); + self.experience_level.store(level, Ordering::Relaxed); + self.experience_progress.store(progress); + self.experience_points.store(points, Ordering::Relaxed); + } + + self.enchantment_seed.store( + nbt.get_int("XpSeed").unwrap_or_else(rand::random), + Ordering::Relaxed, ); + self.score + .store(nbt.get_int("Score").unwrap_or(0), Ordering::Relaxed); + if let Some(sleep_timer) = nbt.get_short("SleepTimer") + && sleep_timer > 0 + { + self.sleeping_since.store(Some(sleep_timer as u8)); + } + + self.seen_credits.store( + nbt.get_bool("seenCredits").unwrap_or(false), + Ordering::Relaxed, + ); + self.spawn_extra_particles_on_fall.store( + nbt.get_bool("spawn_extra_particles_on_fall") + .unwrap_or(false), + Ordering::Relaxed, + ); + + let gamemode = nbt + .get_int("playerGameType") + .or_else(|| nbt.get_byte("playerGameType").map(i32::from)) + .and_then(|val| GameMode::try_from(val).ok()) + .unwrap_or_else(|| self.gamemode.load()); + + self.gamemode.store(gamemode); + self.previous_gamemode.store( - nbt.get_byte("previousPlayerGameType") - .and_then(|byte| GameMode::try_from(byte).ok()), + nbt.get_int("previousPlayerGameType") + .or_else(|| nbt.get_byte("previousPlayerGameType").map(i32::from)) + .and_then(|val| GameMode::try_from(val).ok()), + ); + + { + let mut abilities = self.abilities.lock().await; + abilities.set_for_gamemode(gamemode); + abilities.read_nbt(nbt); + if gamemode == GameMode::Creative { + abilities.allow_flying = true; + abilities.creative = true; + abilities.invulnerable = true; + } else if gamemode == GameMode::Spectator { + abilities.allow_flying = true; + abilities.creative = false; + abilities.invulnerable = true; + } + } + + self.living_entity.entity.invulnerable.store( + matches!(gamemode, GameMode::Creative | GameMode::Spectator), + Ordering::Relaxed, ); self.has_played_before.store( @@ -5995,7 +6098,11 @@ impl EntityBase for Player { self.hunger_manager.read_nbt_non_mut(nbt).await; - if let Some(air) = nbt.get_int("AirSupply") { + if let Some(air) = nbt + .get_short("Air") + .map(i32::from) + .or_else(|| nbt.get_int("AirSupply")) + { self.breath_manager .air_supply .store(air.clamp(0, super::breath::MAX_AIR), Ordering::Relaxed); @@ -6007,8 +6114,28 @@ impl EntityBase for Player { ); } - // Load any saved spawnpoint data (SpawnX/SpawnY/SpawnZ, SpawnDimension, SpawnForced) - if let (Some(x), Some(y), Some(z)) = ( + // Load any saved spawnpoint data (both vanilla "respawn" compound and legacy SpawnX/SpawnY/SpawnZ) + if let Some(respawn_compound) = nbt.get_compound("respawn") { + let dim = respawn_compound + .get_string("dimension") + .and_then(|s| Dimension::from_name(s).cloned()) + .unwrap_or_else(|| self.world().dimension.clone()); + let pos = if let Some(pos_array) = respawn_compound.get_int_array("pos") + && pos_array.len() >= 3 + { + BlockPos(Vector3::new(pos_array[0], pos_array[1], pos_array[2])) + } else { + BlockPos(Vector3::new(0, 0, 0)) + }; + let yaw = respawn_compound.get_float("angle").unwrap_or(0.0); + let force = respawn_compound.get_bool("forced").unwrap_or(false); + *self.respawn_point.lock().await = Some(RespawnPoint { + dimension: dim, + position: pos, + yaw, + force, + }); + } else if let (Some(x), Some(y), Some(z)) = ( nbt.get_int("SpawnX"), nbt.get_int("SpawnY"), nbt.get_int("SpawnZ"), @@ -6025,10 +6152,6 @@ impl EntityBase for Player { force, }); } - self.enchantment_seed.store( - nbt.get_int("XpSeed").unwrap_or(rand::random()), - Ordering::Relaxed, - ); self.root_vehicle_uuid.store(read_root_vehicle(nbt)); self.stats.lock().await.read_nbt(nbt); }) @@ -6091,15 +6214,7 @@ impl NBTStorage for Abilities { fn read_nbt<'a>(&'a mut self, nbt: &'a mut NbtCompound) -> NbtFuture<'a, ()> { Box::pin(async move { - if let Some(component) = nbt.get_compound("abilities") { - self.invulnerable = component.get_bool("invulnerable").unwrap_or(false); - self.flying = component.get_bool("flying").unwrap_or(false); - self.allow_flying = component.get_bool("mayfly").unwrap_or(false); - self.creative = component.get_bool("instabuild").unwrap_or(false); - self.allow_modify_world = component.get_bool("mayBuild").unwrap_or(false); - self.fly_speed = component.get_float("flySpeed").unwrap_or(0.05); - self.walk_speed = component.get_float("walkSpeed").unwrap_or(0.1); - } + self.read_nbt(nbt); }) } } @@ -6121,6 +6236,18 @@ impl Default for Abilities { } impl Abilities { + pub fn read_nbt(&mut self, nbt: &NbtCompound) { + if let Some(component) = nbt.get_compound("abilities") { + self.invulnerable = component.get_bool("invulnerable").unwrap_or(false); + self.flying = component.get_bool("flying").unwrap_or(false); + self.allow_flying = component.get_bool("mayfly").unwrap_or(false); + self.creative = component.get_bool("instabuild").unwrap_or(false); + self.allow_modify_world = component.get_bool("mayBuild").unwrap_or(true); + self.fly_speed = component.get_float("flySpeed").unwrap_or(0.05); + self.walk_speed = component.get_float("walkSpeed").unwrap_or(0.1); + } + } + pub const fn set_for_gamemode(&mut self, gamemode: GameMode) { match gamemode { GameMode::Creative => { diff --git a/crates/pumpkin/src/entity/projectile/eye_of_ender.rs b/crates/pumpkin/src/entity/projectile/eye_of_ender.rs index 19122cfb6..8ef3902ca 100644 --- a/crates/pumpkin/src/entity/projectile/eye_of_ender.rs +++ b/crates/pumpkin/src/entity/projectile/eye_of_ender.rs @@ -209,7 +209,38 @@ impl EntityBase for EyeOfEnder { fn get_item_entity(self: Arc) -> Option> { None } + fn cast_any(&self) -> &dyn std::any::Any { self } + + fn send_java_spawn_packet<'a>( + &'a self, + client: &'a crate::net::java::JavaClient, + ) -> EntityBaseFuture<'a, ()> { + Box::pin(async move { + let spawn_packet = self.entity.create_spawn_packet(); + if let Ok(data) = client.serialize_packet(&spawn_packet) { + client.enqueue_packet(data).await; + } + + if client.version.load() >= pumpkin_data::packet::CURRENT_MC_VERSION { + let metadata = Metadata::new( + pumpkin_data::tracked_data::eye_of_ender::ITEM_STACK, + ItemStackSerializer::from(self.item_stack.lock().await.clone()), + ); + let mut data = Vec::new(); + if metadata.write(&mut data, &client.version.load()).is_ok() { + data.push(255); + let meta_packet = pumpkin_protocol::java::client::play::CSetEntityMetadata::new( + self.entity.entity_id.into(), + data.into(), + ); + if let Ok(meta_data) = client.serialize_packet(&meta_packet) { + client.enqueue_packet(meta_data).await; + } + } + } + }) + } } diff --git a/crates/pumpkin/src/net/java/login/encryption_response.rs b/crates/pumpkin/src/net/java/login/encryption_response.rs index 1e5790470..af4e1856c 100644 --- a/crates/pumpkin/src/net/java/login/encryption_response.rs +++ b/crates/pumpkin/src/net/java/login/encryption_response.rs @@ -43,7 +43,7 @@ impl PendingConnection { ); self.kick(TextComponent::text("Failed to verify encryption token")) .await; - return; + return Some(PacketHandlerResult::Stop); } let Ok(shared_secret) = server.decrypt(&encryption_response.shared_secret).await else { diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs index b4b006ffd..b799d33ee 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs @@ -39,6 +39,10 @@ pub enum PluginInitError { CallInitPluginFailed(wasmtime::Error), #[error("Calling `get_metadata` failed: {0}")] CallGetMetadataFailed(wasmtime::Error), + #[error("Failed to get absolute path: {0}")] + PathResolutionFailed(std::io::Error), + #[error("Failed to create cache: {0}")] + CacheCreationFailed(wasmtime::Error), } pub struct PluginRuntime { @@ -61,14 +65,14 @@ impl PluginRuntime { let mut config = wasmtime::Config::new(); config.wasm_component_model(true); config.wasm_component_model_async(true); - let mut path = std::path::absolute(path.as_ref()).expect("Failed to get absolute path"); + let mut path = + std::path::absolute(path.as_ref()).map_err(PluginInitError::PathResolutionFailed)?; path.pop(); path.push("cache"); let mut cache_config = CacheConfig::new(); cache_config.with_directory(&path); - config.cache(Some( - Cache::new(cache_config).expect("Failed to create cache"), - )); + let cache = Cache::new(cache_config).map_err(PluginInitError::CacheCreationFailed)?; + config.cache(Some(cache)); config.gc_support(true); config.wasm_gc(true); diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs index 29661340a..75fe28496 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs @@ -90,7 +90,7 @@ pub fn strip_pumpkin_sections(wasm_bytes: &[u8]) -> Result, String> { for payload in parser.parse_all(wasm_bytes) { match payload { Ok(Payload::Version { ref range, .. }) => { - last_valid_end = range.end; + last_valid_end = range.end as usize; } Ok(Payload::CustomSection(cs)) => { if cs.name() == PUMPKIN_METADATA_SECTION @@ -98,12 +98,12 @@ pub fn strip_pumpkin_sections(wasm_bytes: &[u8]) -> Result, String> { || cs.name() == "pumpkin.signature" { } else { - last_valid_end = cs.range().end; + last_valid_end = cs.range().end as usize; } } Ok(p) => { if let Some((_, range)) = p.as_section() { - last_valid_end = range.end; + last_valid_end = range.end as usize; } } Err(_) => { diff --git a/crates/pumpkin/src/world/mod.rs b/crates/pumpkin/src/world/mod.rs index 9e3aeacbf..a1c797046 100644 --- a/crates/pumpkin/src/world/mod.rs +++ b/crates/pumpkin/src/world/mod.rs @@ -4821,7 +4821,7 @@ impl World { let view_distance = get_view_distance(player).get() as i32; if is_within_view_distance(chunk_pos, center, view_distance) { - // player.client.try_enqueue_spawn_packet(entity); + player.client.try_enqueue_spawn_packet(entity); } } } diff --git a/tools/pumpkin-codegen/Cargo.toml b/tools/pumpkin-codegen/Cargo.toml index 5b44fee3f..e5a33a46e 100644 --- a/tools/pumpkin-codegen/Cargo.toml +++ b/tools/pumpkin-codegen/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] } serde_repr = { version = "0.1" } serde_json = { version = "1.0", features = ["preserve_order"] } -wit-encoder = "0.256.0" +wit-encoder = "0.257" semver = "1.0" rayon = "1.12.0"