From 2c8b7c5c2c9297273abfba8f7743f1bc25f166b1 Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 28 Sep 2025 13:10:04 -0545 Subject: upgrade bevy to 0.17.0-rc.2 --- CHANGELOG.md | 3 + Cargo.lock | 292 ++++++++------------- Cargo.toml | 12 +- azalea-client/src/client.rs | 75 ++---- azalea-client/src/entity_query.rs | 31 ++- azalea-client/src/player.rs | 4 +- azalea-client/src/plugins/attack.rs | 8 +- azalea-client/src/plugins/auto_reconnect.rs | 6 +- azalea-client/src/plugins/chat/handler.rs | 4 +- azalea-client/src/plugins/chat/mod.rs | 20 +- azalea-client/src/plugins/chunks.rs | 18 +- azalea-client/src/plugins/client_information.rs | 8 +- azalea-client/src/plugins/connection.rs | 10 +- azalea-client/src/plugins/disconnect.rs | 8 +- azalea-client/src/plugins/events.rs | 23 +- azalea-client/src/plugins/interact/mod.rs | 23 +- azalea-client/src/plugins/inventory.rs | 213 +++++++-------- azalea-client/src/plugins/join.rs | 12 +- azalea-client/src/plugins/login.rs | 10 +- azalea-client/src/plugins/mining.rs | 79 +++--- azalea-client/src/plugins/movement.rs | 41 ++- azalea-client/src/plugins/packet/config/events.rs | 33 +-- azalea-client/src/plugins/packet/config/mod.rs | 11 +- azalea-client/src/plugins/packet/game/events.rs | 48 ++-- azalea-client/src/plugins/packet/game/mod.rs | 39 +-- azalea-client/src/plugins/packet/login/events.rs | 22 +- azalea-client/src/plugins/packet/login/mod.rs | 16 +- azalea-client/src/plugins/packet/mod.rs | 43 +-- azalea-client/src/plugins/pong.rs | 13 +- azalea-client/src/plugins/respawn.rs | 6 +- azalea-client/src/test_utils/simulation.rs | 15 +- azalea-client/tests/correct_movement.rs | 2 +- azalea-client/tests/correct_sneak_movement.rs | 2 +- .../tests/correct_sprint_sneak_movement.rs | 2 +- azalea-client/tests/mine_block_rollback.rs | 2 +- azalea-client/tests/mine_block_timing.rs | 2 +- azalea-client/tests/mine_block_without_rollback.rs | 2 +- azalea-client/tests/packet_order.rs | 2 +- .../tests/packet_order_set_carried_item.rs | 4 +- azalea-client/tests/receive_start_config_packet.rs | 15 +- azalea-client/tests/reply_to_ping_with_pong.rs | 14 +- azalea-entity/src/plugin/mod.rs | 6 +- azalea/examples/nearest_entity.rs | 4 +- azalea/examples/testbot/commands/debug.rs | 24 +- azalea/src/accept_resource_packs.rs | 2 +- azalea/src/auto_respawn.rs | 4 +- azalea/src/auto_tool.rs | 12 +- azalea/src/bot.rs | 17 +- azalea/src/container.rs | 15 +- azalea/src/nearest_entity.rs | 4 +- azalea/src/pathfinder/debug.rs | 6 +- azalea/src/pathfinder/goto_event.rs | 4 +- azalea/src/pathfinder/mod.rs | 55 ++-- azalea/src/pathfinder/moves/mod.rs | 14 +- azalea/src/pathfinder/simulation.rs | 5 +- azalea/src/pathfinder/tests.rs | 4 +- azalea/src/swarm/chat.rs | 53 ++-- azalea/src/swarm/events.rs | 6 +- 58 files changed, 615 insertions(+), 813 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cad1953a..d635191e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ is breaking anyways, semantic versioning is not followed. ### Changed +- Update to Bevy 0.17. +- `Client::query`, `map_component`, and `map_get_component` were replaced by `Client::query_self`. + ### Fixed ## [0.14.0+mc1.21.8] - 2025-09-28 diff --git a/Cargo.lock b/Cargo.lock index 654c287a..732b2c30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,7 +230,7 @@ dependencies = [ "bevy_log", "bevy_tasks", "criterion", - "derive_more 2.0.1", + "derive_more", "futures", "futures-lite", "indexmap", @@ -239,7 +239,7 @@ dependencies = [ "num-traits", "parking_lot", "rand 0.9.2", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "thiserror 2.0.16", "tokio", @@ -357,7 +357,7 @@ dependencies = [ "bevy_tasks", "bevy_time", "chrono", - "derive_more 2.0.1", + "derive_more", "indexmap", "minecraft_folder_path", "parking_lot", @@ -420,7 +420,7 @@ dependencies = [ "azalea-world", "bevy_app", "bevy_ecs", - "derive_more 2.0.1", + "derive_more", "enum-as-inner", "nohash-hasher", "parking_lot", @@ -554,10 +554,10 @@ dependencies = [ "azalea-registry", "bevy_ecs", "criterion", - "derive_more 2.0.1", + "derive_more", "nohash-hasher", "parking_lot", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "thiserror 2.0.16", "tracing", @@ -598,9 +598,9 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bevy_app" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4491cc4c718ae76b4c6883df58b94cc88b32dcd894ea8d5b603c7c7da72ca967" +checksum = "43895cb389531d74f8dab16418f31d8855c7656dacf4cced363e8bc19ece8fde" dependencies = [ "bevy_derive", "bevy_ecs", @@ -621,9 +621,9 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b837bf6c51806b10ebfa9edf1844ad80a3a0760d6c5fac4e90761df91a8901a" +checksum = "2cb3ece117a6052bd2b9af37d9f3933e96524fc04d4e0789c873fb0798b82699" dependencies = [ "bevy_macro_utils", "quote", @@ -632,9 +632,9 @@ dependencies = [ [[package]] name = "bevy_ecs" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2bf6521aae57a0ec3487c4bfb59e36c4a378e834b626a4bea6a885af2fdfe7" +checksum = "e7ae89df258af27286fafc1503ffa9dc095d747f10fc94f4e1932f54da40d819" dependencies = [ "arrayvec", "bevy_ecs_macros", @@ -646,13 +646,13 @@ dependencies = [ "bitflags", "bumpalo", "concurrent-queue", - "derive_more 1.0.0", - "disqualified", + "derive_more", "fixedbitset 0.5.7", "indexmap", "log", "nonmax", "serde", + "slotmap", "smallvec", "thiserror 2.0.16", "variadics_please", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38748d6f3339175c582d751f410fb60a93baf2286c3deb7efebb0878dce7f413" +checksum = "40b142eb11acc9827116708b7963e1fc179ab70ed297c03d41f97cc215ce243e" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -672,13 +672,14 @@ dependencies = [ [[package]] name = "bevy_log" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a61ee8aef17a974f5ca481dcedf0c2bd52670e231d4c4bc9ddef58328865f9" +checksum = "be79d161555350d3e7adbe30ceaa7d07d3a064893a5cdf15a198df9dd9c7b27e" dependencies = [ "android_log-sys", "bevy_app", "bevy_ecs", + "bevy_platform", "bevy_utils", "tracing", "tracing-log", @@ -689,9 +690,9 @@ dependencies = [ [[package]] name = "bevy_macro_utils" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052eeebcb8e7e072beea5031b227d9a290f8a7fbbb947573ab6ec81df0fb94be" +checksum = "d6f66d0c0b425c6181de04b867e744170275e037d35b1c7f8cdc324f57c78358" dependencies = [ "parking_lot", "proc-macro2", @@ -702,40 +703,43 @@ dependencies = [ [[package]] name = "bevy_platform" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7573dc824a1b08b4c93fdbe421c53e1e8188e9ca1dd74a414455fe571facb47" +checksum = "4cc4d19e7ef9e6360ce16a54406135f3ca76f7b4de3d4fae520847d3fad2deed" dependencies = [ - "cfg-if", "critical-section", "foldhash", - "getrandom 0.2.16", - "hashbrown 0.15.5", + "futures-channel", + "getrandom 0.3.3", + "hashbrown", + "js-sys", "portable-atomic", "portable-atomic-util", "serde", "spin", + "wasm-bindgen", + "wasm-bindgen-futures", "web-time", ] [[package]] name = "bevy_ptr" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7370d0e46b60e071917711d0860721f5347bc958bf325975ae6913a5dfcf01" +checksum = "d129fa79c6ec9a63acbb3719eac25a10a4edfdfc88f83af40b963c1cfa540b98" [[package]] name = "bevy_reflect" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daeb91a63a1a4df00aa58da8cc4ddbd4b9f16ab8bb647c5553eb156ce36fa8c2" +checksum = "2457c391687f5773f86bcc1e7dab5529b050069733c6639bf1d3283965f3c0f1" dependencies = [ "assert_type_match", "bevy_platform", "bevy_ptr", "bevy_reflect_derive", "bevy_utils", - "derive_more 1.0.0", + "derive_more", "disqualified", "downcast-rs", "erased-serde", @@ -752,11 +756,12 @@ dependencies = [ [[package]] name = "bevy_reflect_derive" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ddadc55fe16b45faaa54ab2f9cb00548013c74812e8b018aa172387103cce6" +checksum = "73fdd27630d61ddded2a3c6c8b2c846f7fbdce863472ea20cab1ae73674fa454" dependencies = [ "bevy_macro_utils", + "indexmap", "proc-macro2", "quote", "syn", @@ -765,31 +770,28 @@ dependencies = [ [[package]] name = "bevy_tasks" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b674242641cab680688fc3b850243b351c1af49d4f3417a576debd6cca8dcf5" +checksum = "8fec5efc5d9db0cb3841e8e06b484f4adb071ec45819a4dc07d475a684b5ab75" dependencies = [ "async-channel", "async-executor", "async-task", "atomic-waker", "bevy_platform", - "cfg-if", "concurrent-queue", "crossbeam-queue", - "derive_more 1.0.0", - "futures-channel", + "derive_more", "futures-lite", "heapless", "pin-project", - "wasm-bindgen-futures", ] [[package]] name = "bevy_time" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc98eb356c75be04fbbc77bb3d8ffa24c8bacd99f76111cee23d444be6ac8c9c" +checksum = "f8519fc3d9d76d80d1f0236c2d1aa6b57ffbc0dbe0670d6439b79a2baf9f8dec" dependencies = [ "bevy_app", "bevy_ecs", @@ -802,34 +804,15 @@ dependencies = [ [[package]] name = "bevy_utils" -version = "0.16.1" +version = "0.17.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f7a8905a125d2017e8561beefb7f2f5e67e93ff6324f072ad87c5fd6ec3b99" +checksum = "3b0a08df94307630c54474c3766e6ac6641408c8d550e42ca6c528d4ab305b7b" dependencies = [ "bevy_platform", + "disqualified", "thread_local", ] -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", -] - [[package]] name = "bitflags" version = "2.9.4" @@ -863,6 +846,26 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "bytemuck" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -900,15 +903,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfb8" version = "0.8.1" @@ -977,17 +971,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.48" @@ -1246,34 +1229,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl 1.0.0", -] - [[package]] name = "derive_more" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ - "derive_more-impl 2.0.1", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", + "derive_more-impl", ] [[package]] @@ -1285,6 +1247,7 @@ dependencies = [ "proc-macro2", "quote", "syn", + "unicode-xid", ] [[package]] @@ -1459,9 +1422,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "form_urlencoded" @@ -1619,19 +1582,13 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glam" -version = "0.29.3" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" +checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460" dependencies = [ - "serde", + "serde_core", ] -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - [[package]] name = "half" version = "2.6.0" @@ -1653,20 +1610,14 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ "equivalent", "serde", ] -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - [[package]] name = "heapless" version = "0.8.0" @@ -1955,7 +1906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown", ] [[package]] @@ -2073,16 +2024,6 @@ version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - [[package]] name = "libm" version = "0.2.15" @@ -2157,12 +2098,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d60a6352e005f1f86008644a9fe336a66f74c94428182162cc69eb8c6fff458d" -[[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" @@ -2219,16 +2154,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nonmax" version = "0.5.5" @@ -2534,16 +2459,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" version = "1.0.101" @@ -2564,7 +2479,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", "socket2 0.6.0", "thiserror 2.0.16", @@ -2584,7 +2499,7 @@ dependencies = [ "lru-slab", "rand 0.9.2", "ring", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", "rustls-pki-types", "slab", @@ -2835,12 +2750,6 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -3104,6 +3013,15 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.15.1" @@ -3154,9 +3072,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" dependencies = [ "portable-atomic", ] @@ -3376,18 +3294,31 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" dependencies = [ "indexmap", "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ "winnow", ] @@ -3481,15 +3412,12 @@ dependencies = [ [[package]] name = "tracing-oslog" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" +checksum = "d76902d2a8d5f9f55a81155c08971734071968c90f2d9bfe645fe700579b2950" dependencies = [ - "bindgen", "cc", "cfg-if", - "once_cell", - "parking_lot", "tracing-core", "tracing-subscriber", ] @@ -3765,14 +3693,16 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "24.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2" dependencies = [ "bitflags", + "bytemuck", "js-sys", "log", "serde", + "thiserror 2.0.16", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index b2e1642b..b8259867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,11 +34,11 @@ anyhow = "1" async-compat = "0.2" async-recursion = "1" base64 = "0.22" -bevy_app = "0.16" -bevy_ecs = { version = "0.16", default-features = false } -bevy_log = "0.16" -bevy_tasks = "0.16" -bevy_time = "0.16" +bevy_app = "0.17.0-rc.2" +bevy_ecs = { version = "0.17.0-rc.2", default-features = false } +bevy_log = "0.17.0-rc.2" +bevy_tasks = "0.17.0-rc.2" +bevy_time = "0.17.0-rc.2" byteorder = "1" cfb8 = "0.8" chrono = { version = "0.4", default-features = false } @@ -67,7 +67,7 @@ rand = "0.9" regex = "1" reqwest = { version = "0.12", default-features = false } rsa = "0.10.0-rc.8" -signature = "=3.0.0-rc.4" # TODO: Remove when rsa is fixed. +signature = "=3.0.0-rc.4" # TODO: Remove when rsa is fixed. rsa_public_encrypt_pkcs1 = "0.4" rustc-hash = "2" serde = "1" diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 368419c9..6faca385 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -14,7 +14,7 @@ use azalea_core::{ tick::GameTick, }; use azalea_entity::{ - EntityUpdateSet, PlayerAbilities, Position, + EntityUpdateSystems, PlayerAbilities, Position, dimensions::EntityDimensions, indexing::{EntityIdIndex, EntityUuidIndex}, metadata::Health, @@ -29,7 +29,7 @@ use azalea_protocol::{ use azalea_world::{Instance, InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance}; use bevy_app::{App, AppExit, Plugin, PluginsState, SubApp, Update}; use bevy_ecs::{ - event::EventCursor, + message::MessageCursor, prelude::*, schedule::{InternedScheduleLabel, LogLevel, ScheduleBuildSettings}, }; @@ -216,7 +216,7 @@ impl Client { let (start_join_callback_tx, mut start_join_callback_rx) = mpsc::unbounded_channel::(); - ecs_lock.lock().send_event(StartJoinServerEvent { + ecs_lock.lock().write_message(StartJoinServerEvent { account, connect_opts, event_sender, @@ -244,20 +244,17 @@ impl Client { /// The OwnedReadHalf for the TCP connection is in one of the tasks, so it /// automatically closes the connection when that's dropped. pub fn disconnect(&self) { - self.ecs.lock().send_event(DisconnectEvent { + self.ecs.lock().write_message(DisconnectEvent { entity: self.entity, reason: None, }); } - pub fn raw_connection<'a>(&'a self, ecs: &'a mut World) -> &'a RawConnection { - self.query::<&RawConnection>(ecs) + pub fn with_raw_connection(&self, f: impl FnOnce(&RawConnection) -> R) -> R { + self.query_self::<&RawConnection, _>(f) } - pub fn raw_connection_mut<'a>( - &'a self, - ecs: &'a mut World, - ) -> bevy_ecs::world::Mut<'a, RawConnection> { - self.query::<&mut RawConnection>(ecs) + pub fn with_raw_connection_mut(&self, f: impl FnOnce(Mut<'_, RawConnection>) -> R) -> R { + self.query_self::<&mut RawConnection, _>(f) } /// Get a component from this client. This will clone the component and @@ -283,15 +280,16 @@ impl Client { /// let world_name = client.component::(); /// # } pub fn component(&self) -> T { - self.query::<&T>(&mut self.ecs.lock()).clone() + self.query_self::<&T, _>(|t| t.clone()) } /// Get a component from this client, or `None` if it doesn't exist. /// /// If the component can't be cloned, try [`Self::map_component`] instead. - /// You may also have to use [`Self::ecs`] and [`Self::query`] directly. + /// + /// You may also have to use [`Self::with_query`] directly. pub fn get_component(&self) -> Option { - self.query::>(&mut self.ecs.lock()).cloned() + self.query_self::, _>(|t| t.cloned()) } /// Get a resource from the ECS. This will clone the resource and return it. @@ -313,42 +311,6 @@ impl Client { f(value) } - /// Get a required component for this client and call the given function. - /// - /// Similar to [`Self::component`], but doesn't clone the component since - /// it's passed as a reference. [`Self::ecs`] will remain locked while the - /// callback is being run. - /// - /// If the component is not guaranteed to be present, use - /// [`Self::get_component`] instead. - /// - /// # Panics - /// - /// This will panic if the component doesn't exist on the client. - /// - /// ``` - /// # use azalea_client::{Client, local_player::Hunger}; - /// # fn example(bot: &Client) { - /// let hunger = bot.map_component::(|h| h.food); - /// # } - /// ``` - pub fn map_component(&self, f: impl FnOnce(&T) -> R) -> R { - let mut ecs = self.ecs.lock(); - let value = self.query::<&T>(&mut ecs); - f(value) - } - - /// Optionally get a component for this client and call the given function. - /// - /// Similar to [`Self::get_component`], but doesn't clone the component - /// since it's passed as a reference. [`Self::ecs`] will remain locked - /// while the callback is being run. - pub fn map_get_component(&self, f: impl FnOnce(&T) -> R) -> Option { - let mut ecs = self.ecs.lock(); - let value = self.query::>(&mut ecs); - value.map(f) - } - /// Get an `RwLock` with a reference to our (potentially shared) world. /// /// This gets the [`Instance`] from the client's [`InstanceHolder`] @@ -377,8 +339,7 @@ impl Client { /// Returns whether we have a received the login packet yet. pub fn logged_in(&self) -> bool { // the login packet tells us the world name - self.query::>(&mut self.ecs.lock()) - .is_some() + self.query_self::, _>(|ins| ins.is_some()) } } @@ -485,13 +446,13 @@ impl Client { /// Convert an ECS `Entity` to a [`MinecraftEntityId`]. pub fn minecraft_entity_by_ecs_entity(&self, entity: Entity) -> Option { - self.map_component::(|entity_id_index| { + self.query_self::<&EntityIdIndex, _>(|entity_id_index| { entity_id_index.get_by_ecs_entity(entity) }) } /// Convert a [`MinecraftEntityId`] to an ECS `Entity`. pub fn ecs_entity_by_minecraft_entity(&self, entity: MinecraftEntityId) -> Option { - self.map_component::(|entity_id_index| { + self.query_self::<&EntityIdIndex, _>(|entity_id_index| { entity_id_index.get_by_minecraft_entity(entity) }) } @@ -600,7 +561,7 @@ impl Plugin for AzaleaPlugin { ( // add GameProfileComponent when we get an AddPlayerEvent retroactively_add_game_profile_component - .after(EntityUpdateSet::Index) + .after(EntityUpdateSystems::Index) .after(crate::join::handle_start_join_server_event), ), ) @@ -722,9 +683,9 @@ async fn run_schedule_loop( /// /// This is based on Bevy's `should_exit` function: https://github.com/bevyengine/bevy/blob/b9fd7680e78c4073dfc90fcfdc0867534d92abe0/crates/bevy_app/src/app.rs#L1292 fn should_exit(ecs: &mut World) -> Option { - let mut reader = EventCursor::default(); + let mut reader = MessageCursor::default(); - let events = ecs.get_resource::>()?; + let events = ecs.get_resource::>()?; let mut events = reader.read(events); if events.len() != 0 { diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs index 55b86d6c..c21380fc 100644 --- a/azalea-client/src/entity_query.rs +++ b/azalea-client/src/entity_query.rs @@ -6,7 +6,7 @@ use azalea_world::InstanceName; use bevy_ecs::{ component::Component, entity::Entity, - query::{QueryData, QueryFilter, ROQueryItem}, + query::{QueryData, QueryFilter, QueryItem, ROQueryItem}, world::World, }; use parking_lot::Mutex; @@ -14,26 +14,29 @@ use parking_lot::Mutex; use crate::Client; impl Client { - /// A convenience function for getting components of our player's entity. + /// A convenience function for getting components from our client's entity. /// /// # Examples /// ``` /// # use azalea_world::InstanceName; /// # fn example(mut client: azalea_client::Client) { - /// let is_logged_in = client - /// .query::>(&mut client.ecs.lock()) - /// .is_some(); + /// let is_logged_in = client.query_self::, _>(|ins| ins.is_some()); /// # } /// ``` - pub fn query<'w, D: QueryData>(&self, ecs: &'w mut World) -> D::Item<'w> { - ecs.query::() - .get_mut(ecs, self.entity) - .unwrap_or_else(|_| { - panic!( - "Our client is missing a required component {:?}", - any::type_name::() - ) - }) + /// + /// # Panics + /// + /// This will panic if the component doesn't exist on the client. + pub fn query_self(&self, f: impl FnOnce(QueryItem) -> R) -> R { + let mut ecs = self.ecs.lock(); + let mut qs = ecs.query::(); + let res = qs.get_mut(&mut ecs, self.entity).unwrap_or_else(|_| { + panic!( + "Our client is missing a required component {:?}", + any::type_name::() + ) + }); + f(res) } /// Quickly returns a lightweight [`Entity`] for an arbitrary entity that diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index d696d133..46596e48 100644 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -4,7 +4,7 @@ use azalea_core::game_type::GameMode; use azalea_entity::indexing::EntityUuidIndex; use bevy_ecs::{ component::Component, - event::EventReader, + message::MessageReader, system::{Commands, Res}, }; use derive_more::{Deref, DerefMut}; @@ -44,7 +44,7 @@ pub struct GameProfileComponent(pub GameProfile); /// `ClientboundGamePacket::AddPlayer` handler though. pub fn retroactively_add_game_profile_component( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, entity_uuid_index: Res, ) { for event in events.read() { diff --git a/azalea-client/src/plugins/attack.rs b/azalea-client/src/plugins/attack.rs index 7d730bb7..47e45896 100644 --- a/azalea-client/src/plugins/attack.rs +++ b/azalea-client/src/plugins/attack.rs @@ -19,7 +19,7 @@ use crate::{ pub struct AttackPlugin; impl Plugin for AttackPlugin { fn build(&self, app: &mut App) { - app.add_event::() + app.add_message::() .add_systems( Update, handle_attack_event @@ -45,7 +45,7 @@ impl Plugin for AttackPlugin { impl Client { /// Attack the entity with the given id. pub fn attack(&self, entity: Entity) { - self.ecs.lock().send_event(AttackEvent { + self.ecs.lock().write_message(AttackEvent { entity: self.entity, target: entity, }); @@ -148,14 +148,14 @@ pub fn handle_attack_queued( /// Queues up an attack packet for next tick by inserting the [`AttackQueued`] /// component to our client. -#[derive(Event)] +#[derive(Message)] pub struct AttackEvent { /// Our client entity that will send the packets to attack. pub entity: Entity, /// The entity that will be attacked. pub target: Entity, } -pub fn handle_attack_event(mut events: EventReader, mut commands: Commands) { +pub fn handle_attack_event(mut events: MessageReader, mut commands: Commands) { for event in events.read() { commands.entity(event.entity).insert(AttackQueued { target: event.target, diff --git a/azalea-client/src/plugins/auto_reconnect.rs b/azalea-client/src/plugins/auto_reconnect.rs index 1391545f..bff72e5a 100644 --- a/azalea-client/src/plugins/auto_reconnect.rs +++ b/azalea-client/src/plugins/auto_reconnect.rs @@ -39,8 +39,8 @@ impl Plugin for AutoReconnectPlugin { pub fn start_rejoin_on_disconnect( mut commands: Commands, - mut disconnect_events: EventReader, - mut connection_failed_events: EventReader, + mut disconnect_events: MessageReader, + mut connection_failed_events: MessageReader, auto_reconnect_delay_res: Option>, auto_reconnect_delay_query: Query<&AutoReconnectDelay>, ) { @@ -85,7 +85,7 @@ fn get_delay( pub fn rejoin_after_delay( mut commands: Commands, - mut join_events: EventWriter, + mut join_events: MessageWriter, query: Query<( Entity, &InternalReconnectAfter, diff --git a/azalea-client/src/plugins/chat/handler.rs b/azalea-client/src/plugins/chat/handler.rs index a289eb14..d71bcbd1 100644 --- a/azalea-client/src/plugins/chat/handler.rs +++ b/azalea-client/src/plugins/chat/handler.rs @@ -21,7 +21,7 @@ use crate::{Account, chat_signing::ChatSigningSession, packet::game::SendPacketE /// preserved if multiple chat messages and commands are sent at the same time. /// /// [`SendChatEvent`]: super::SendChatEvent -#[derive(Event)] +#[derive(Message)] pub struct SendChatKindEvent { pub entity: Entity, pub content: String, @@ -29,7 +29,7 @@ pub struct SendChatKindEvent { } pub fn handle_send_chat_kind_event( - mut events: EventReader, + mut events: MessageReader, mut commands: Commands, mut query: Query<(&Account, &mut ChatSigningSession)>, ) { diff --git a/azalea-client/src/plugins/chat/mod.rs b/azalea-client/src/plugins/chat/mod.rs index f8ef3251..098b6543 100644 --- a/azalea-client/src/plugins/chat/mod.rs +++ b/azalea-client/src/plugins/chat/mod.rs @@ -19,9 +19,9 @@ use crate::client::Client; pub struct ChatPlugin; impl Plugin for ChatPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() - .add_event::() + app.add_message::() + .add_message::() + .add_message::() .add_systems( Update, (handle_send_chat_event, handle_send_chat_kind_event).chain(), @@ -189,7 +189,7 @@ impl Client { /// handles checking whether the message is a command and using the /// proper packet for you, so you should use that instead. pub fn write_chat_packet(&self, message: &str) { - self.ecs.lock().send_event(SendChatKindEvent { + self.ecs.lock().write_message(SendChatKindEvent { entity: self.entity, content: message.to_string(), kind: ChatKind::Message, @@ -202,7 +202,7 @@ impl Client { /// You can also just use [`Client::chat`] and start your message with a `/` /// to send a command. pub fn write_command_packet(&self, command: &str) { - self.ecs.lock().send_event(SendChatKindEvent { + self.ecs.lock().write_message(SendChatKindEvent { entity: self.entity, content: command.to_string(), kind: ChatKind::Command, @@ -219,7 +219,7 @@ impl Client { /// # } /// ``` pub fn chat(&self, content: impl Into) { - self.ecs.lock().send_event(SendChatEvent { + self.ecs.lock().write_message(SendChatEvent { entity: self.entity, content: content.into(), }); @@ -227,22 +227,22 @@ impl Client { } /// A client received a chat message packet. -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ChatReceivedEvent { pub entity: Entity, pub packet: ChatPacket, } /// Send a chat message (or command, if it starts with a slash) to the server. -#[derive(Event)] +#[derive(Message)] pub struct SendChatEvent { pub entity: Entity, pub content: String, } pub fn handle_send_chat_event( - mut events: EventReader, - mut send_chat_kind_events: EventWriter, + mut events: MessageReader, + mut send_chat_kind_events: MessageWriter, ) { for event in events.read() { if event.content.starts_with('/') { diff --git a/azalea-client/src/plugins/chunks.rs b/azalea-client/src/plugins/chunks.rs index ff4f8a53..f8d2c523 100644 --- a/azalea-client/src/plugins/chunks.rs +++ b/azalea-client/src/plugins/chunks.rs @@ -35,13 +35,13 @@ impl Plugin for ChunksPlugin { .before(InventorySet) .before(perform_respawn), ) - .add_event::() - .add_event::() - .add_event::(); + .add_message::() + .add_message::() + .add_message::(); } } -#[derive(Event)] +#[derive(Message)] pub struct ReceiveChunkEvent { pub entity: Entity, pub packet: ClientboundLevelChunkWithLight, @@ -54,18 +54,18 @@ pub struct ChunkBatchInfo { pub old_samples_weight: u32, } -#[derive(Event)] +#[derive(Message)] pub struct ChunkBatchStartEvent { pub entity: Entity, } -#[derive(Event)] +#[derive(Message)] pub struct ChunkBatchFinishedEvent { pub entity: Entity, pub batch_size: u32, } pub fn handle_receive_chunk_event( - mut events: EventReader, + mut events: MessageReader, mut query: Query<&InstanceHolder>, ) { for event in events.read() { @@ -132,7 +132,7 @@ impl ChunkBatchInfo { pub fn handle_chunk_batch_start_event( mut query: Query<&mut ChunkBatchInfo>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok(mut chunk_batch_info) = query.get_mut(event.entity) { @@ -143,7 +143,7 @@ pub fn handle_chunk_batch_start_event( pub fn handle_chunk_batch_finished_event( mut query: Query<&mut ChunkBatchInfo>, - mut events: EventReader, + mut events: MessageReader, mut commands: Commands, ) { for event in events.read() { diff --git a/azalea-client/src/plugins/client_information.rs b/azalea-client/src/plugins/client_information.rs index d30b5329..499b8ab5 100644 --- a/azalea-client/src/plugins/client_information.rs +++ b/azalea-client/src/plugins/client_information.rs @@ -60,11 +60,9 @@ impl Client { /// # } /// ``` pub async fn set_client_information(&self, client_information: ClientInformation) { - { - let mut ecs = self.ecs.lock(); - let mut client_information_mut = self.query::<&mut ClientInformation>(&mut ecs); - *client_information_mut = client_information.clone(); - } + self.query_self::<&mut ClientInformation, _>(|mut ci| { + *ci = client_information.clone(); + }); if self.logged_in() { debug!( diff --git a/azalea-client/src/plugins/connection.rs b/azalea-client/src/plugins/connection.rs index f439ac33..54966703 100644 --- a/azalea-client/src/plugins/connection.rs +++ b/azalea-client/src/plugins/connection.rs @@ -124,7 +124,7 @@ pub fn read_packets(ecs: &mut World) { } } - queued_packet_events.send_events(ecs); + queued_packet_events.write_messages(ecs); } fn poll_all_writer_tasks(mut conn_query: Query<&mut RawConnection>) { @@ -149,10 +149,10 @@ pub struct QueuedPacketEvents { game: Vec, } impl QueuedPacketEvents { - fn send_events(&mut self, ecs: &mut World) { - ecs.send_event_batch(self.login.drain(..)); - ecs.send_event_batch(self.config.drain(..)); - ecs.send_event_batch(self.game.drain(..)); + fn write_messages(&mut self, ecs: &mut World) { + ecs.write_message_batch(self.login.drain(..)); + ecs.write_message_batch(self.config.drain(..)); + ecs.write_message_batch(self.game.drain(..)); } } diff --git a/azalea-client/src/plugins/disconnect.rs b/azalea-client/src/plugins/disconnect.rs index 3cb9e82a..95950ae9 100644 --- a/azalea-client/src/plugins/disconnect.rs +++ b/azalea-client/src/plugins/disconnect.rs @@ -19,7 +19,7 @@ use crate::{ pub struct DisconnectPlugin; impl Plugin for DisconnectPlugin { fn build(&self, app: &mut App) { - app.add_event::().add_systems( + app.add_message::().add_systems( PostUpdate, ( update_read_packets_task_running_component, @@ -45,7 +45,7 @@ impl Plugin for DisconnectPlugin { /// /// [`ConnectionFailedEvent`]: crate::join::ConnectionFailedEvent -#[derive(Event)] +#[derive(Message)] pub struct DisconnectEvent { pub entity: Entity, pub reason: Option, @@ -82,7 +82,7 @@ pub struct RemoveOnDisconnectBundle { /// a [`DisconnectEvent`]. pub fn remove_components_from_disconnected_players( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, mut loaded_by_query: Query<&mut azalea_entity::LoadedBy>, ) { for DisconnectEvent { entity, reason } in events.read() { @@ -125,7 +125,7 @@ fn update_read_packets_task_running_component( #[allow(clippy::type_complexity)] fn disconnect_on_connection_dead( query: Query<(Entity, &IsConnectionAlive), (Changed, With)>, - mut disconnect_events: EventWriter, + mut disconnect_events: MessageWriter, ) { for (entity, &is_connection_alive) in &query { if !*is_connection_alive { diff --git a/azalea-client/src/plugins/events.rs b/azalea-client/src/plugins/events.rs index 581a3e81..bc8a7a98 100644 --- a/azalea-client/src/plugins/events.rs +++ b/azalea-client/src/plugins/events.rs @@ -35,7 +35,7 @@ use crate::{ // use. // - Add the event struct in PacketPlugin::build // - (in the `impl Plugin for PacketPlugin`) -// - To get the event writer, you have to get an EventWriter. +// - To get the event writer, you have to get an MessageWriter. // Look at other packets in packet/game/mod.rs for examples. // // At this point, you've created a new ECS event. That's annoying for bots to @@ -195,7 +195,10 @@ pub fn spawn_listener( } } -pub fn chat_listener(query: Query<&LocalPlayerEvents>, mut events: EventReader) { +pub fn chat_listener( + query: Query<&LocalPlayerEvents>, + mut events: MessageReader, +) { for event in events.read() { if let Ok(local_player_events) = query.get(event.entity) { let _ = local_player_events.send(Event::Chat(event.packet.clone())); @@ -213,7 +216,7 @@ pub fn tick_listener(query: Query<&LocalPlayerEvents, With>) { #[cfg(feature = "packet-event")] pub fn packet_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok(local_player_events) = query.get(event.entity) { @@ -224,7 +227,7 @@ pub fn packet_listener( pub fn add_player_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { let local_player_events = query @@ -236,7 +239,7 @@ pub fn add_player_listener( pub fn update_player_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { let local_player_events = query @@ -248,7 +251,7 @@ pub fn update_player_listener( pub fn remove_player_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { let local_player_events = query @@ -258,7 +261,7 @@ pub fn remove_player_listener( } } -pub fn death_listener(query: Query<&LocalPlayerEvents>, mut events: EventReader) { +pub fn death_listener(query: Query<&LocalPlayerEvents>, mut events: MessageReader) { for event in events.read() { if let Ok(local_player_events) = query.get(event.entity) { let _ = local_player_events.send(Event::Death(event.packet.clone().map(|p| p.into()))); @@ -277,7 +280,7 @@ pub fn dead_component_listener(query: Query<&LocalPlayerEvents, Added>) { pub fn keepalive_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { let local_player_events = query @@ -289,7 +292,7 @@ pub fn keepalive_listener( pub fn disconnect_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok(local_player_events) = query.get(event.entity) { @@ -300,7 +303,7 @@ pub fn disconnect_listener( pub fn receive_chunk_listener( query: Query<&LocalPlayerEvents>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok(local_player_events) = query.get(event.entity) { diff --git a/azalea-client/src/plugins/interact/mod.rs b/azalea-client/src/plugins/interact/mod.rs index dc60ef66..b5defdf0 100644 --- a/azalea-client/src/plugins/interact/mod.rs +++ b/azalea-client/src/plugins/interact/mod.rs @@ -48,8 +48,7 @@ use crate::{ pub struct InteractPlugin; impl Plugin for InteractPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() + app.add_message::() .add_systems( Update, ( @@ -63,7 +62,6 @@ impl Plugin for InteractPlugin { update_hit_result_component .after(clamp_look_direction) .after(update_last_bounding_box), - handle_swing_arm_event, ) .after(InventorySet) .after(MoveEventsSet) @@ -89,7 +87,7 @@ impl Client { /// Note that this may trigger anticheats as it doesn't take into account /// whether you're actually looking at the block. pub fn block_interact(&self, position: BlockPos) { - self.ecs.lock().send_event(StartUseItemEvent { + self.ecs.lock().write_message(StartUseItemEvent { entity: self.entity, hand: InteractionHand::MainHand, force_block: Some(position), @@ -104,7 +102,7 @@ impl Client { /// If we're looking at a block or entity, then it will be clicked. Also see /// [`Client::block_interact`]. pub fn start_use_item(&self) { - self.ecs.lock().send_event(StartUseItemEvent { + self.ecs.lock().write_message(StartUseItemEvent { entity: self.entity, hand: InteractionHand::MainHand, force_block: None, @@ -209,7 +207,7 @@ impl BlockStatePredictionHandler { /// This event just inserts the [`StartUseItemQueued`] component on the given /// entity. #[doc(alias("right click"))] -#[derive(Event)] +#[derive(Message)] pub struct StartUseItemEvent { pub entity: Entity, pub hand: InteractionHand, @@ -218,7 +216,7 @@ pub struct StartUseItemEvent { } pub fn handle_start_use_item_event( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { commands.entity(event.entity).insert(StartUseItemQueued { @@ -427,23 +425,18 @@ pub fn can_use_game_master_blocks( /// Swing your arm. This is purely a visual effect and won't interact with /// anything in the world. -#[derive(Event, Clone, Debug)] +#[derive(EntityEvent, Clone, Debug)] pub struct SwingArmEvent { pub entity: Entity, } -pub fn handle_swing_arm_trigger(trigger: Trigger, mut commands: Commands) { +pub fn handle_swing_arm_trigger(swing_arm: On, mut commands: Commands) { commands.trigger(SendPacketEvent::new( - trigger.event().entity, + swing_arm.entity, ServerboundSwing { hand: InteractionHand::MainHand, }, )); } -pub fn handle_swing_arm_event(mut events: EventReader, mut commands: Commands) { - for event in events.read() { - commands.trigger(event.clone()); - } -} #[allow(clippy::type_complexity)] fn update_attributes_for_held_item( diff --git a/azalea-client/src/plugins/inventory.rs b/azalea-client/src/plugins/inventory.rs index 968a805b..448f9e95 100644 --- a/azalea-client/src/plugins/inventory.rs +++ b/azalea-client/src/plugins/inventory.rs @@ -28,22 +28,10 @@ use crate::{Client, packet::game::SendPacketEvent, respawn::perform_respawn}; pub struct InventoryPlugin; impl Plugin for InventoryPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() + app.add_message::() .add_systems( Update, - ( - handle_set_selected_hotbar_slot_event, - handle_menu_opened_event, - handle_container_click_event, - handle_container_close_event, - handle_client_side_close_container_event, - ) - .chain() + handle_set_selected_hotbar_slot_event .in_set(InventorySet) .before(perform_respawn), ) @@ -53,6 +41,7 @@ impl Plugin for InventoryPlugin { ) .add_observer(handle_client_side_close_container_trigger) .add_observer(handle_menu_opened_trigger) + .add_observer(handle_container_close_event) .add_observer(handle_set_container_content_trigger); } } @@ -64,9 +53,7 @@ impl Client { /// Return the menu that is currently open. If no menu is open, this will /// have the player's inventory. pub fn menu(&self) -> Menu { - let mut ecs = self.ecs.lock(); - let inventory = self.query::<&Inventory>(&mut ecs); - inventory.menu().clone() + self.query_self::<&Inventory, _>(|inv| inv.menu().clone()) } /// Returns the index of the hotbar slot that's currently selected. @@ -77,15 +64,17 @@ impl Client { /// /// You can use [`Self::set_selected_hotbar_slot`] to change it. pub fn selected_hotbar_slot(&self) -> u8 { - let mut ecs = self.ecs.lock(); - let inventory = self.query::<&Inventory>(&mut ecs); - inventory.selected_hotbar_slot + self.query_self::<&Inventory, _>(|inv| inv.selected_hotbar_slot) } /// Update the selected hotbar slot index. /// /// This will run next `Update`, so you might want to call /// `bot.wait_updates(1)` after calling this if you're using `azalea`. + /// + /// # Panics + /// + /// This will panic if `new_hotbar_slot_index` is not in the range 0..=8. pub fn set_selected_hotbar_slot(&self, new_hotbar_slot_index: u8) { assert!( new_hotbar_slot_index < 9, @@ -93,7 +82,7 @@ impl Client { ); let mut ecs = self.ecs.lock(); - ecs.send_event(SetSelectedHotbarSlotEvent { + ecs.write_message(SetSelectedHotbarSlotEvent { entity: self.entity, slot: new_hotbar_slot_index, }); @@ -736,30 +725,25 @@ impl Default for Inventory { /// To watch for the menu being closed, you could use /// [`ClientsideCloseContainerEvent`]. To close it manually, use /// [`CloseContainerEvent`]. -#[derive(Event, Debug, Clone)] +#[derive(EntityEvent, Debug, Clone)] pub struct MenuOpenedEvent { pub entity: Entity, pub window_id: i32, pub menu_type: MenuKind, pub title: FormattedText, } -fn handle_menu_opened_trigger(event: Trigger, mut query: Query<&mut Inventory>) { +fn handle_menu_opened_trigger(event: On, mut query: Query<&mut Inventory>) { let mut inventory = query.get_mut(event.entity).unwrap(); inventory.id = event.window_id; inventory.container_menu = Some(Menu::from_kind(event.menu_type)); inventory.container_menu_title = Some(event.title.clone()); } -pub fn handle_menu_opened_event(mut events: EventReader, mut commands: Commands) { - for event in events.read() { - commands.trigger(event.clone()); - } -} /// Tell the server that we want to close a container. /// /// Note that this is also sent when the client closes its own inventory, even /// though there is no packet for opening its inventory. -#[derive(Event)] +#[derive(EntityEvent)] pub struct CloseContainerEvent { pub entity: Entity, /// The ID of the container to close. 0 for the player's inventory. If this @@ -767,31 +751,28 @@ pub struct CloseContainerEvent { pub id: i32, } fn handle_container_close_event( - query: Query<(Entity, &Inventory)>, - mut events: EventReader, - mut client_side_events: EventWriter, + close_container: On, mut commands: Commands, + query: Query<(Entity, &Inventory)>, ) { - for event in events.read() { - let (entity, inventory) = query.get(event.entity).unwrap(); - if event.id != inventory.id { - warn!( - "Tried to close container with ID {}, but the current container ID is {}", - event.id, inventory.id - ); - continue; - } - - commands.trigger(SendPacketEvent::new( - entity, - ServerboundContainerClose { - container_id: inventory.id, - }, - )); - client_side_events.write(ClientsideCloseContainerEvent { - entity: event.entity, - }); + let (entity, inventory) = query.get(close_container.entity).unwrap(); + if close_container.id != inventory.id { + warn!( + "Tried to close container with ID {}, but the current container ID is {}", + close_container.id, inventory.id + ); + return; } + + commands.trigger(SendPacketEvent::new( + entity, + ServerboundContainerClose { + container_id: inventory.id, + }, + )); + commands.trigger(ClientsideCloseContainerEvent { + entity: close_container.entity, + }); } /// A Bevy trigger that's fired when our client closed a container. @@ -802,12 +783,12 @@ fn handle_container_close_event( /// /// If you want to watch for a container being opened, you should use /// [`MenuOpenedEvent`]. -#[derive(Event, Clone)] +#[derive(EntityEvent, Clone)] pub struct ClientsideCloseContainerEvent { pub entity: Entity, } pub fn handle_client_side_close_container_trigger( - event: Trigger, + event: On, mut query: Query<&mut Inventory>, ) { let mut inventory = query.get_mut(event.entity).unwrap(); @@ -838,126 +819,120 @@ pub fn handle_client_side_close_container_trigger( inventory.id = 0; inventory.container_menu_title = None; } -pub fn handle_client_side_close_container_event( - mut commands: Commands, - mut events: EventReader, -) { - for event in events.read() { - commands.trigger(event.clone()); - } -} -#[derive(Event, Debug)] +#[derive(EntityEvent, Debug)] pub struct ContainerClickEvent { pub entity: Entity, pub window_id: i32, pub operation: ClickOperation, } pub fn handle_container_click_event( + mut commands: Commands, + container_click: On, mut query: Query<( Entity, &mut Inventory, Option<&PlayerAbilities>, &InstanceName, )>, - mut events: EventReader, - mut commands: Commands, instance_container: Res, ) { - for event in events.read() { - let (entity, mut inventory, player_abilities, instance_name) = - query.get_mut(event.entity).unwrap(); - if inventory.id != event.window_id { - error!( - "Tried to click container with ID {}, but the current container ID is {}. Click packet won't be sent.", - event.window_id, inventory.id - ); - continue; - } - - let Some(instance) = instance_container.get(instance_name) else { - continue; - }; - - let old_slots = inventory.menu().slots(); - inventory.simulate_click( - &event.operation, - player_abilities.unwrap_or(&PlayerAbilities::default()), + let (entity, mut inventory, player_abilities, instance_name) = + query.get_mut(container_click.entity).unwrap(); + if inventory.id != container_click.window_id { + error!( + "Tried to click container with ID {}, but the current container ID is {}. Click packet won't be sent.", + container_click.window_id, inventory.id ); - let new_slots = inventory.menu().slots(); + return; + } - let registry_holder = &instance.read().registries; - - // see which slots changed after clicking and put them in the map the server - // uses this to check if we desynced - let mut changed_slots: IndexMap = IndexMap::new(); - for (slot_index, old_slot) in old_slots.iter().enumerate() { - let new_slot = &new_slots[slot_index]; - if old_slot != new_slot { - changed_slots.insert( - slot_index as u16, - HashedStack::from_item_stack(new_slot, registry_holder), - ); - } - } + let Some(instance) = instance_container.get(instance_name) else { + return; + }; - commands.trigger(SendPacketEvent::new( - entity, - ServerboundContainerClick { - container_id: event.window_id, - state_id: inventory.state_id, - slot_num: event.operation.slot_num().map(|n| n as i16).unwrap_or(-999), - button_num: event.operation.button_num(), - click_type: event.operation.click_type(), - changed_slots, - carried_item: HashedStack::from_item_stack(&inventory.carried, registry_holder), - }, - )); + let old_slots = inventory.menu().slots(); + inventory.simulate_click( + &container_click.operation, + player_abilities.unwrap_or(&PlayerAbilities::default()), + ); + let new_slots = inventory.menu().slots(); + + let registry_holder = &instance.read().registries; + + // see which slots changed after clicking and put them in the map the server + // uses this to check if we desynced + let mut changed_slots: IndexMap = IndexMap::new(); + for (slot_index, old_slot) in old_slots.iter().enumerate() { + let new_slot = &new_slots[slot_index]; + if old_slot != new_slot { + changed_slots.insert( + slot_index as u16, + HashedStack::from_item_stack(new_slot, registry_holder), + ); + } } + + commands.trigger(SendPacketEvent::new( + entity, + ServerboundContainerClick { + container_id: container_click.window_id, + state_id: inventory.state_id, + slot_num: container_click + .operation + .slot_num() + .map(|n| n as i16) + .unwrap_or(-999), + button_num: container_click.operation.button_num(), + click_type: container_click.operation.click_type(), + changed_slots, + carried_item: HashedStack::from_item_stack(&inventory.carried, registry_holder), + }, + )); } /// Sent from the server when the contents of a container are replaced. /// /// Usually triggered by the `ContainerSetContent` packet. -#[derive(Event)] +#[derive(EntityEvent)] pub struct SetContainerContentEvent { pub entity: Entity, pub slots: Vec, pub container_id: i32, } pub fn handle_set_container_content_trigger( - event: Trigger, + set_container_content: On, mut query: Query<&mut Inventory>, ) { - let mut inventory = query.get_mut(event.entity).unwrap(); + let mut inventory = query.get_mut(set_container_content.entity).unwrap(); - if event.container_id != inventory.id { + if set_container_content.container_id != inventory.id { warn!( "Got SetContainerContentEvent for container with ID {}, but the current container ID is {}", - event.container_id, inventory.id + set_container_content.container_id, inventory.id ); return; } let menu = inventory.menu_mut(); - for (i, slot) in event.slots.iter().enumerate() { + for (i, slot) in set_container_content.slots.iter().enumerate() { if let Some(slot_mut) = menu.slot_mut(i) { *slot_mut = slot.clone(); } } } -/// An ECS event to switch our hand to a different hotbar slot. +/// An ECS message to switch our hand to a different hotbar slot. /// /// This is equivalent to using the scroll wheel or number keys in Minecraft. -#[derive(Event)] +#[derive(Message)] pub struct SetSelectedHotbarSlotEvent { pub entity: Entity, /// The hotbar slot to select. This should be in the range 0..=8. pub slot: u8, } pub fn handle_set_selected_hotbar_slot_event( - mut events: EventReader, + mut events: MessageReader, mut query: Query<&mut Inventory>, ) { for event in events.read() { diff --git a/azalea-client/src/plugins/join.rs b/azalea-client/src/plugins/join.rs index ed2d6ed3..b9878370 100644 --- a/azalea-client/src/plugins/join.rs +++ b/azalea-client/src/plugins/join.rs @@ -30,8 +30,8 @@ use crate::{ pub struct JoinPlugin; impl Plugin for JoinPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() + app.add_message::() + .add_message::() .add_systems( Update, ( @@ -47,7 +47,7 @@ impl Plugin for JoinPlugin { /// /// This won't do anything if a client with the Account UUID is already /// connected to the server. -#[derive(Event, Debug)] +#[derive(Message, Debug)] pub struct StartJoinServerEvent { pub account: Account, pub connect_opts: ConnectOpts, @@ -74,7 +74,7 @@ pub struct ConnectOpts { /// This isn't sent if we're kicked later, see [`DisconnectEvent`]. /// /// [`DisconnectEvent`]: crate::disconnect::DisconnectEvent -#[derive(Event)] +#[derive(Message)] pub struct ConnectionFailedEvent { pub entity: Entity, pub error: ConnectionError, @@ -82,7 +82,7 @@ pub struct ConnectionFailedEvent { pub fn handle_start_join_server_event( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, mut entity_uuid_index: ResMut, connection_query: Query<&RawConnection>, ) { @@ -184,7 +184,7 @@ pub struct CreateConnectionTask(pub Task>); pub fn poll_create_connection_task( mut commands: Commands, mut query: Query<(Entity, &mut CreateConnectionTask, &Account)>, - mut connection_failed_events: EventWriter, + mut connection_failed_events: MessageWriter, ) { for (entity, mut task, account) in query.iter_mut() { if let Some(poll_res) = future::block_on(future::poll_once(&mut task.0)) { diff --git a/azalea-client/src/plugins/login.rs b/azalea-client/src/plugins/login.rs index 05e45cae..25919c8c 100644 --- a/azalea-client/src/plugins/login.rs +++ b/azalea-client/src/plugins/login.rs @@ -23,12 +23,12 @@ impl Plugin for LoginPlugin { } } -fn handle_receive_hello_event(trigger: Trigger, mut commands: Commands) { +fn handle_receive_hello_event(receive_hello: On, mut commands: Commands) { let task_pool = IoTaskPool::get(); - let account = trigger.account.clone(); - let packet = trigger.packet.clone(); - let player = trigger.target(); + let account = receive_hello.account.clone(); + let packet = receive_hello.packet.clone(); + let player = receive_hello.entity; let task = task_pool.spawn(auth_with_account(account, packet)); commands.entity(player).insert(AuthTask(task)); @@ -149,7 +149,7 @@ pub async fn auth_with_account( pub fn reply_to_custom_queries( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { trace!("Maybe replying to custom query: {event:?}"); diff --git a/azalea-client/src/plugins/mining.rs b/azalea-client/src/plugins/mining.rs index e42ea866..b4f8adbe 100644 --- a/azalea-client/src/plugins/mining.rs +++ b/azalea-client/src/plugins/mining.rs @@ -26,11 +26,10 @@ use crate::{ pub struct MiningPlugin; impl Plugin for MiningPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() + app.add_message::() + .add_message::() + .add_message::() + .add_message::() .add_systems( GameTick, ( @@ -57,8 +56,7 @@ impl Plugin for MiningPlugin { .after(MoveEventsSet) .after(azalea_entity::update_fluid_on_eyes) .after(crate::interact::pick::update_hit_result_component) - .after(crate::attack::handle_attack_event) - .before(crate::interact::handle_swing_arm_event), + .after(crate::attack::handle_attack_event), ) .add_observer(handle_finish_mining_block_observer); } @@ -72,7 +70,7 @@ impl Client { pub fn start_mining(&self, position: BlockPos) { let mut ecs = self.ecs.lock(); - ecs.send_event(StartMiningBlockEvent { + ecs.write_message(StartMiningBlockEvent { entity: self.entity, position, }); @@ -111,8 +109,8 @@ fn handle_auto_mine( ), With, >, - mut start_mining_block_event: EventWriter, - mut stop_mining_block_event: EventWriter, + mut start_mining_block_event: MessageWriter, + mut stop_mining_block_event: MessageWriter, ) { for ( hit_result_component, @@ -161,14 +159,14 @@ pub struct Mining { /// /// If we're looking at the block then the correct direction will be used, /// otherwise it'll be [`Direction::Down`]. -#[derive(Event, Debug)] +#[derive(Message, Debug)] pub struct StartMiningBlockEvent { pub entity: Entity, pub position: BlockPos, } fn handle_start_mining_block_event( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, mut query: Query<&HitResultComponent>, ) { for event in events.read() { @@ -207,8 +205,8 @@ pub struct MiningQueued { #[allow(clippy::too_many_arguments, clippy::type_complexity)] pub fn handle_mining_queued( mut commands: Commands, - mut attack_block_events: EventWriter, - mut mine_block_progress_events: EventWriter, + mut attack_block_events: MessageWriter, + mut mine_block_progress_events: MessageWriter, query: Query<( Entity, &MiningQueued, @@ -269,12 +267,10 @@ pub fn handle_mining_queued( seq: sequence_number.start_predicting(), }, )); - commands.trigger_targets( - FinishMiningBlockEvent { - position: mining_queued.position, - }, + commands.trigger(FinishMiningBlockEvent { entity, - ); + position: mining_queued.position, + }); **mine_delay = 5; commands.trigger(SwingArmEvent { entity }); } else if mining.is_none() @@ -328,12 +324,10 @@ pub fn handle_mining_queued( ) >= 1. { // block was broken instantly (instamined) - commands.trigger_targets( - FinishMiningBlockEvent { - position: mining_queued.position, - }, + commands.trigger(FinishMiningBlockEvent { entity, - ); + position: mining_queued.position, + }); } else { let mining = Mining { pos: mining_queued.position, @@ -369,7 +363,7 @@ pub fn handle_mining_queued( } } -#[derive(Event)] +#[derive(Message)] pub struct MineBlockProgressEvent { pub entity: Entity, pub position: BlockPos, @@ -378,7 +372,7 @@ pub struct MineBlockProgressEvent { /// A player left clicked on a block, used for stuff like interacting with note /// blocks. -#[derive(Event)] +#[derive(Message)] pub struct AttackBlockEvent { pub entity: Entity, pub position: BlockPos, @@ -441,13 +435,14 @@ pub struct MineBlockPos(pub Option); pub struct MineItem(pub ItemStack); /// A trigger that's sent when we completed mining a block. -#[derive(Event)] +#[derive(EntityEvent)] pub struct FinishMiningBlockEvent { + pub entity: Entity, pub position: BlockPos, } pub fn handle_finish_mining_block_observer( - trigger: Trigger, + finish_mining_block: On, mut query: Query<( &InstanceName, &LocalGameMode, @@ -459,7 +454,7 @@ pub fn handle_finish_mining_block_observer( )>, instances: Res, ) { - let event = trigger.event(); + let event = finish_mining_block.event(); let ( instance_name, @@ -469,7 +464,7 @@ pub fn handle_finish_mining_block_observer( permission_level, player_pos, mut prediction_handler, - ) = query.get_mut(trigger.target()).unwrap(); + ) = query.get_mut(finish_mining_block.entity).unwrap(); let instance_lock = instances.get(instance_name).unwrap(); let instance = instance_lock.read(); if check_is_interaction_restricted(&instance, event.position, &game_mode.current, inventory) { @@ -515,14 +510,14 @@ pub fn handle_finish_mining_block_observer( } /// Abort mining a block. -#[derive(Event)] +#[derive(Message)] pub struct StopMiningBlockEvent { pub entity: Entity, } pub fn handle_stop_mining_block_event( - mut events: EventReader, + mut events: MessageReader, mut commands: Commands, - mut mine_block_progress_events: EventWriter, + mut mine_block_progress_events: MessageWriter, mut query: Query<(&MineBlockPos, &mut MineProgress)>, ) { for event in events.read() { @@ -567,7 +562,7 @@ pub fn continue_mining_block( &mut BlockStatePredictionHandler, )>, mut commands: Commands, - mut mine_block_progress_events: EventWriter, + mut mine_block_progress_events: MessageWriter, instances: Res, ) { for ( @@ -603,12 +598,10 @@ pub fn continue_mining_block( seq: prediction_handler.start_predicting(), }, )); - commands.trigger_targets( - FinishMiningBlockEvent { - position: mining.pos, - }, + commands.trigger(FinishMiningBlockEvent { entity, - ); + position: mining.pos, + }); commands.trigger(SwingArmEvent { entity }); } else if mining.force || is_same_mining_target( @@ -648,12 +641,10 @@ pub fn continue_mining_block( // repeatedly inserts MiningQueued commands.entity(entity).remove::<(Mining, MiningQueued)>(); trace!("finished mining block at {:?}", mining.pos); - commands.trigger_targets( - FinishMiningBlockEvent { - position: mining.pos, - }, + commands.trigger(FinishMiningBlockEvent { entity, - ); + position: mining.pos, + }); commands.trigger(SendPacketEvent::new( entity, ServerboundPlayerAction { diff --git a/azalea-client/src/plugins/movement.rs b/azalea-client/src/plugins/movement.rs index 48e7ecea..c76158c5 100644 --- a/azalea-client/src/plugins/movement.rs +++ b/azalea-client/src/plugins/movement.rs @@ -65,9 +65,9 @@ pub struct MovementPlugin; impl Plugin for MovementPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() - .add_event::() + app.add_message::() + .add_message::() + .add_message::() .add_systems( Update, (handle_sprint, handle_walk, handle_knockback) @@ -105,9 +105,7 @@ impl Client { /// If you're making a realistic client, calling this function every tick is /// recommended. pub fn set_jumping(&self, jumping: bool) { - let mut ecs = self.ecs.lock(); - let mut jumping_mut = self.query::<&mut Jumping>(&mut ecs); - **jumping_mut = jumping; + self.query_self::<&mut Jumping, _>(|mut j| **j = jumping); } /// Returns whether the player will try to jump next tick. @@ -116,18 +114,14 @@ impl Client { } pub fn set_crouching(&self, crouching: bool) { - let mut ecs = self.ecs.lock(); - let mut physics_state = self.query::<&mut PhysicsState>(&mut ecs); - physics_state.trying_to_crouch = crouching; + self.query_self::<&mut PhysicsState, _>(|mut p| p.trying_to_crouch = crouching); } /// Whether the client is currently trying to sneak. /// /// You may want to check the [`Pose`] instead. pub fn crouching(&self) -> bool { - let mut ecs = self.ecs.lock(); - let physics_state = self.query::<&PhysicsState>(&mut ecs); - physics_state.trying_to_crouch + self.query_self::<&PhysicsState, _>(|p| p.trying_to_crouch) } /// Sets the direction the client is looking. `y_rot` is yaw (looking to the @@ -135,10 +129,9 @@ impl Client { /// numbers from the vanilla f3 screen. /// `y_rot` goes from -180 to 180, and `x_rot` goes from -90 to 90. pub fn set_direction(&self, y_rot: f32, x_rot: f32) { - let mut ecs = self.ecs.lock(); - let mut look_direction = self.query::<&mut LookDirection>(&mut ecs); - - look_direction.update(LookDirection::new(y_rot, x_rot)); + self.query_self::<&mut LookDirection, _>(|mut ld| { + ld.update(LookDirection::new(y_rot, x_rot)); + }); } /// Returns the direction the client is looking. The first value is the y @@ -557,7 +550,7 @@ impl Client { /// ``` pub fn walk(&self, direction: WalkDirection) { let mut ecs = self.ecs.lock(); - ecs.send_event(StartWalkEvent { + ecs.write_message(StartWalkEvent { entity: self.entity, direction, }); @@ -580,7 +573,7 @@ impl Client { /// ``` pub fn sprint(&self, direction: SprintDirection) { let mut ecs = self.ecs.lock(); - ecs.send_event(StartSprintEvent { + ecs.write_message(StartSprintEvent { entity: self.entity, direction, }); @@ -591,7 +584,7 @@ impl Client { /// non-local entities. /// /// To stop walking or sprinting, send this event with `WalkDirection::None`. -#[derive(Event, Debug)] +#[derive(Message, Debug)] pub struct StartWalkEvent { pub entity: Entity, pub direction: WalkDirection, @@ -600,7 +593,7 @@ pub struct StartWalkEvent { /// The system that makes the player start walking when they receive a /// [`StartWalkEvent`]. pub fn handle_walk( - mut events: EventReader, + mut events: MessageReader, mut query: Query<(&mut PhysicsState, &mut Sprinting, &mut Attributes)>, ) { for event in events.read() { @@ -615,7 +608,7 @@ pub fn handle_walk( /// An event sent when the client starts sprinting. This does not get sent for /// non-local entities. -#[derive(Event)] +#[derive(Message)] pub struct StartSprintEvent { pub entity: Entity, pub direction: SprintDirection, @@ -624,7 +617,7 @@ pub struct StartSprintEvent { /// [`StartSprintEvent`]. pub fn handle_sprint( mut query: Query<&mut PhysicsState>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok(mut physics_state) = query.get_mut(event.entity) { @@ -673,7 +666,7 @@ fn has_enough_impulse_to_start_sprinting(physics_state: &PhysicsState) -> bool { /// `KnockbackKind::Set` is used for normal knockback and `KnockbackKind::Add` /// is used for explosions, but some servers (notably Hypixel) use explosions /// for knockback. -#[derive(Event)] +#[derive(Message)] pub struct KnockbackEvent { pub entity: Entity, pub knockback: KnockbackType, @@ -684,7 +677,7 @@ pub enum KnockbackType { Add(Vec3), } -pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: EventReader) { +pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: MessageReader) { for event in events.read() { if let Ok(mut physics) = query.get_mut(event.entity) { match event.knockback { diff --git a/azalea-client/src/plugins/packet/config/events.rs b/azalea-client/src/plugins/packet/config/events.rs index a9237e75..be5cfdb1 100644 --- a/azalea-client/src/plugins/packet/config/events.rs +++ b/azalea-client/src/plugins/packet/config/events.rs @@ -9,7 +9,7 @@ use tracing::{debug, error}; use crate::{InConfigState, connection::RawConnection}; -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ReceiveConfigPacketEvent { /// The client entity that received the packet. pub entity: Entity, @@ -19,8 +19,9 @@ pub struct ReceiveConfigPacketEvent { /// An event for sending a packet to the server while we're in the /// `configuration` state. -#[derive(Event, Clone)] +#[derive(EntityEvent, Clone)] pub struct SendConfigPacketEvent { + #[event_target] pub sent_by: Entity, pub packet: ServerboundConfigPacket, } @@ -32,41 +33,33 @@ impl SendConfigPacketEvent { } pub fn handle_outgoing_packets_observer( - trigger: Trigger, + send_config_packet: On, mut query: Query<(&mut RawConnection, Option<&InConfigState>)>, ) { - let event = trigger.event(); - if let Ok((mut raw_conn, in_configuration_state)) = query.get_mut(event.sent_by) { + if let Ok((mut raw_conn, in_configuration_state)) = query.get_mut(send_config_packet.sent_by) { if in_configuration_state.is_none() { error!( "Tried to send a configuration packet {:?} while not in configuration state", - event.packet + send_config_packet.packet ); return; } - debug!("Sending config packet: {:?}", event.packet); - if let Err(e) = raw_conn.write(event.packet.clone()) { + debug!("Sending config packet: {:?}", send_config_packet.packet); + if let Err(e) = raw_conn.write(send_config_packet.packet.clone()) { error!("Failed to send packet: {e}"); } } } -/// A system that converts [`SendConfigPacketEvent`] events into triggers so -/// they get received by [`handle_outgoing_packets_observer`]. -pub fn handle_outgoing_packets( - mut commands: Commands, - mut events: EventReader, -) { - for event in events.read() { - commands.trigger(event.clone()); - } -} /// A Bevy trigger that's sent when our client receives a [`ClientboundPing`] /// packet in the config state. /// -/// See [`PingEvent`] for more information. +/// Also see [`PingEvent`]. /// /// [`ClientboundPing`]: azalea_protocol::packets::config::ClientboundPing /// [`PingEvent`]: crate::packet::game::PingEvent #[derive(Event, Debug, Clone)] -pub struct ConfigPingEvent(pub azalea_protocol::packets::config::ClientboundPing); +pub struct ConfigPingEvent { + pub entity: Entity, + pub packet: azalea_protocol::packets::config::ClientboundPing, +} diff --git a/azalea-client/src/plugins/packet/config/mod.rs b/azalea-client/src/plugins/packet/config/mod.rs index 416019e8..e8bb017d 100644 --- a/azalea-client/src/plugins/packet/config/mod.rs +++ b/azalea-client/src/plugins/packet/config/mod.rs @@ -84,7 +84,7 @@ impl ConfigPacketHandler<'_> { pub fn disconnect(&mut self, p: &ClientboundDisconnect) { warn!("Got disconnect packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(DisconnectEvent { entity: self.player, reason: Some(p.reason.clone()), @@ -126,7 +126,7 @@ impl ConfigPacketHandler<'_> { self.player ); - as_system::<(Commands, EventWriter<_>)>(self.ecs, |(mut commands, mut events)| { + as_system::<(Commands, MessageWriter<_>)>(self.ecs, |(mut commands, mut events)| { events.write(KeepAliveEvent { entity: self.player, id: p.id, @@ -142,14 +142,17 @@ impl ConfigPacketHandler<'_> { debug!("Got ping packet (in configuration) {p:?}"); as_system::(self.ecs, |mut commands| { - commands.trigger_targets(ConfigPingEvent(p.clone()), self.player); + commands.trigger(ConfigPingEvent { + entity: self.player, + packet: p.clone(), + }); }); } pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) { debug!("Got resource pack push packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ResourcePackEvent { entity: self.player, id: p.id, diff --git a/azalea-client/src/plugins/packet/game/events.rs b/azalea-client/src/plugins/packet/game/events.rs index e341db3e..4ae51734 100644 --- a/azalea-client/src/plugins/packet/game/events.rs +++ b/azalea-client/src/plugins/packet/game/events.rs @@ -18,9 +18,9 @@ use crate::{client::InGameState, connection::RawConnection, player::PlayerInfo}; /// ``` /// # use azalea_client::packet::game::ReceiveGamePacketEvent; /// # use azalea_protocol::packets::game::ClientboundGamePacket; -/// # use bevy_ecs::event::EventReader; +/// # use bevy_ecs::event::MessageReader; /// -/// fn handle_packets(mut events: EventReader) { +/// fn handle_packets(mut events: MessageReader) { /// for ReceiveGamePacketEvent { entity, packet } in events.read() { /// match packet.as_ref() { /// ClientboundGamePacket::LevelParticles(p) => { @@ -31,7 +31,7 @@ use crate::{client::InGameState, connection::RawConnection, player::PlayerInfo}; /// } /// } /// ``` -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ReceiveGamePacketEvent { /// The client entity that received the packet. pub entity: Entity, @@ -40,8 +40,9 @@ pub struct ReceiveGamePacketEvent { } /// An event for sending a packet to the server while we're in the `game` state. -#[derive(Event, Clone, Debug)] +#[derive(EntityEvent, Clone, Debug)] pub struct SendPacketEvent { + #[event_target] pub sent_by: Entity, pub packet: ServerboundGamePacket, } @@ -53,7 +54,7 @@ impl SendPacketEvent { } pub fn handle_outgoing_packets_observer( - trigger: Trigger, + trigger: On, mut query: Query<(&mut RawConnection, Option<&InGameState>)>, ) { let event = trigger.event(); @@ -76,17 +77,9 @@ pub fn handle_outgoing_packets_observer( } } -/// A system that converts [`SendPacketEvent`] events into triggers so they get -/// received by [`handle_outgoing_packets_observer`]. -pub fn handle_outgoing_packets(mut commands: Commands, mut events: EventReader) { - for event in events.read() { - commands.trigger(event.clone()); - } -} - /// A player joined the game (or more specifically, was added to the tab /// list of a local player). -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct AddPlayerEvent { /// The local player entity that received this event. pub entity: Entity, @@ -94,7 +87,7 @@ pub struct AddPlayerEvent { } /// A player left the game (or maybe is still in the game and was just /// removed from the tab list of a local player). -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct RemovePlayerEvent { /// The local player entity that received this event. pub entity: Entity, @@ -102,7 +95,7 @@ pub struct RemovePlayerEvent { } /// A player was updated in the tab list of a local player (gamemode, display /// name, or latency changed). -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct UpdatePlayerEvent { /// The local player entity that received this event. pub entity: Entity, @@ -112,7 +105,7 @@ pub struct UpdatePlayerEvent { /// Event for when an entity dies. dies. If it's a local player and there's a /// reason in the death screen, the [`ClientboundPlayerCombatKill`] will /// be included. -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct DeathEvent { pub entity: Entity, pub packet: Option, @@ -120,7 +113,7 @@ pub struct DeathEvent { /// A KeepAlive packet is sent from the server to verify that the client is /// still connected. -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct KeepAliveEvent { pub entity: Entity, /// The ID of the keepalive. This is an arbitrary number, but vanilla @@ -128,7 +121,7 @@ pub struct KeepAliveEvent { pub id: u64, } -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ResourcePackEvent { pub entity: Entity, /// The random ID for this request to download the resource pack. The packet @@ -144,7 +137,7 @@ pub struct ResourcePackEvent { /// /// Since the instance is given to you as a weak reference, it won't be able to /// be `upgrade`d if all local players leave it. -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct InstanceLoadedEvent { pub entity: Entity, pub name: ResourceLocation, @@ -156,15 +149,10 @@ pub struct InstanceLoadedEvent { /// /// Also see [`ConfigPingEvent`] which is used for the config state. /// -/// This is not an event and can't be listened to from a normal system, -///so `EventReader` will not work. -/// -/// To use it, add your "system" with `add_observer` instead of `add_systems` -/// and use `Trigger` instead of `EventReader`. -/// -/// The client Entity that received the packet will be attached to the trigger. -/// /// [`ClientboundPing`]: azalea_protocol::packets::game::ClientboundPing /// [`ConfigPingEvent`]: crate::packet::config::ConfigPingEvent -#[derive(Event, Debug, Clone)] -pub struct PingEvent(pub azalea_protocol::packets::game::ClientboundPing); +#[derive(EntityEvent, Debug, Clone)] +pub struct PingEvent { + pub entity: Entity, + pub packet: azalea_protocol::packets::game::ClientboundPing, +} diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs index fc8f34cf..dbdc8e26 100644 --- a/azalea-client/src/plugins/packet/game/mod.rs +++ b/azalea-client/src/plugins/packet/game/mod.rs @@ -207,7 +207,7 @@ impl GamePacketHandler<'_> { ), With, >, - EventWriter, + MessageWriter, ResMut, ResMut, Query<&mut LoadedBy, Without>, @@ -336,7 +336,7 @@ impl GamePacketHandler<'_> { // ends debug!("Got chunk batch start"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(chunks::ChunkBatchStartEvent { entity: self.player, }); @@ -346,7 +346,7 @@ impl GamePacketHandler<'_> { pub fn chunk_batch_finished(&mut self, p: &ClientboundChunkBatchFinished) { debug!("Got chunk batch finished {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(chunks::ChunkBatchFinishedEvent { entity: self.player, batch_size: p.batch_size, @@ -387,7 +387,7 @@ impl GamePacketHandler<'_> { pub fn disconnect(&mut self, p: &ClientboundDisconnect) { warn!("Got disconnect packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(DisconnectEvent { entity: self.player, reason: Some(p.reason.clone()), @@ -440,8 +440,8 @@ impl GamePacketHandler<'_> { as_system::<( Query<&mut TabList>, - EventWriter, - EventWriter, + MessageWriter, + MessageWriter, ResMut, )>( self.ecs, @@ -500,7 +500,7 @@ impl GamePacketHandler<'_> { as_system::<( Query<&mut TabList>, - EventWriter, + MessageWriter, ResMut, )>( self.ecs, @@ -542,7 +542,7 @@ impl GamePacketHandler<'_> { pub fn level_chunk_with_light(&mut self, p: &ClientboundLevelChunkWithLight) { debug!("Got chunk with light packet {} {}", p.x, p.z); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(chunks::ReceiveChunkEvent { entity: self.player, packet: p.clone(), @@ -740,7 +740,7 @@ impl GamePacketHandler<'_> { instance_holder.partial_instance.clone(), move |entity_mut| { entity_mut.world_scope(|world| { - world.send_event(KnockbackEvent { entity, knockback }) + world.write_message(KnockbackEvent { entity, knockback }) }); }, )); @@ -957,7 +957,7 @@ impl GamePacketHandler<'_> { pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) { debug!("Got keep alive packet {p:?} for {:?}", self.player); - as_system::<(EventWriter, Commands)>( + as_system::<(MessageWriter, Commands)>( self.ecs, |(mut keepalive_events, mut commands)| { keepalive_events.write(KeepAliveEvent { @@ -1011,7 +1011,7 @@ impl GamePacketHandler<'_> { pub fn player_chat(&mut self, p: &ClientboundPlayerChat) { debug!("Got player chat packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ChatReceivedEvent { entity: self.player, packet: ChatPacket::Player(Arc::new(p.clone())), @@ -1022,7 +1022,7 @@ impl GamePacketHandler<'_> { pub fn system_chat(&mut self, p: &ClientboundSystemChat) { debug!("Got system chat packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ChatReceivedEvent { entity: self.player, packet: ChatPacket::System(Arc::new(p.clone())), @@ -1033,7 +1033,7 @@ impl GamePacketHandler<'_> { pub fn disguised_chat(&mut self, p: &ClientboundDisguisedChat) { debug!("Got disguised chat packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ChatReceivedEvent { entity: self.player, packet: ChatPacket::Disguised(Arc::new(p.clone())), @@ -1227,7 +1227,7 @@ impl GamePacketHandler<'_> { pub fn explode(&mut self, p: &ClientboundExplode) { trace!("Got explode packet {p:?}"); - as_system::>(self.ecs, |mut knockback_events| { + as_system::>(self.ecs, |mut knockback_events| { if let Some(knockback) = p.knockback { knockback_events.write(KnockbackEvent { entity: self.player, @@ -1278,7 +1278,10 @@ impl GamePacketHandler<'_> { debug!("Got ping packet {p:?}"); as_system::(self.ecs, |mut commands| { - commands.trigger_targets(PingEvent(p.clone()), self.player); + commands.trigger(PingEvent { + entity: self.player, + packet: p.clone(), + }); }); } @@ -1294,7 +1297,7 @@ impl GamePacketHandler<'_> { as_system::<( Commands, Query<(&MinecraftEntityId, Option<&Dead>)>, - EventWriter<_>, + MessageWriter<_>, )>(self.ecs, |(mut commands, mut query, mut events)| { let (entity_id, dead) = query.get_mut(self.player).unwrap(); @@ -1315,7 +1318,7 @@ impl GamePacketHandler<'_> { pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) { debug!("Got resource pack packet {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ResourcePackEvent { entity: self.player, id: p.id, @@ -1343,7 +1346,7 @@ impl GamePacketHandler<'_> { ), With, >, - EventWriter<_>, + MessageWriter<_>, ResMut, Query<&mut LoadedBy, Without>, )>( diff --git a/azalea-client/src/plugins/packet/login/events.rs b/azalea-client/src/plugins/packet/login/events.rs index fc7a6b22..f50c1423 100644 --- a/azalea-client/src/plugins/packet/login/events.rs +++ b/azalea-client/src/plugins/packet/login/events.rs @@ -12,7 +12,7 @@ use tracing::{debug, error}; use super::InLoginState; use crate::{Account, connection::RawConnection}; -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ReceiveLoginPacketEvent { /// The client entity that received the packet. pub entity: Entity, @@ -20,13 +20,14 @@ pub struct ReceiveLoginPacketEvent { pub packet: Arc, } -#[derive(Event, Debug, Clone)] +#[derive(EntityEvent, Debug, Clone)] pub struct ReceiveHelloEvent { + pub entity: Entity, pub account: Account, pub packet: ClientboundHello, } -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct ReceiveCustomQueryEvent { /// The client entity that received the packet. pub entity: Entity, @@ -40,8 +41,9 @@ pub struct ReceiveCustomQueryEvent { } /// Event for sending a login packet to the server. -#[derive(Event, Debug, Clone)] +#[derive(EntityEvent, Debug, Clone)] pub struct SendLoginPacketEvent { + #[event_target] pub sent_by: Entity, pub packet: ServerboundLoginPacket, } @@ -56,7 +58,7 @@ impl SendLoginPacketEvent { } pub fn handle_outgoing_packets_observer( - trigger: Trigger, + trigger: On, mut query: Query<(&mut RawConnection, Option<&InLoginState>)>, ) { let event = trigger.event(); @@ -74,13 +76,3 @@ pub fn handle_outgoing_packets_observer( } } } -/// A system that converts [`SendLoginPacketEvent`] events into triggers so -/// they get received by [`handle_outgoing_packets_observer`]. -pub fn handle_outgoing_packets( - mut commands: Commands, - mut events: EventReader, -) { - for event in events.read() { - commands.trigger(event.clone()); - } -} diff --git a/azalea-client/src/plugins/packet/login/mod.rs b/azalea-client/src/plugins/packet/login/mod.rs index 03e87920..63226124 100644 --- a/azalea-client/src/plugins/packet/login/mod.rs +++ b/azalea-client/src/plugins/packet/login/mod.rs @@ -59,19 +59,17 @@ impl LoginPacketHandler<'_> { ); return; }; - commands.trigger_targets( - ReceiveHelloEvent { - account: account.clone(), - packet: p.clone(), - }, - self.player, - ); + commands.trigger(ReceiveHelloEvent { + entity: self.player, + account: account.clone(), + packet: p.clone(), + }); }); } pub fn login_disconnect(&mut self, p: &ClientboundLoginDisconnect) { debug!("Got disconnect {:?}", p); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(DisconnectEvent { entity: self.player, reason: Some(p.reason.clone()), @@ -120,7 +118,7 @@ impl LoginPacketHandler<'_> { pub fn custom_query(&mut self, p: &ClientboundCustomQuery) { debug!("Got custom query {p:?}"); - as_system::>(self.ecs, |mut events| { + as_system::>(self.ecs, |mut events| { events.write(ReceiveCustomQueryEvent { entity: self.player, packet: p.clone(), diff --git a/azalea-client/src/plugins/packet/mod.rs b/azalea-client/src/plugins/packet/mod.rs index 2602e878..30503d50 100644 --- a/azalea-client/src/plugins/packet/mod.rs +++ b/azalea-client/src/plugins/packet/mod.rs @@ -16,7 +16,7 @@ pub struct PacketPlugin; pub fn death_event_on_0_health( query: Query<(Entity, &Health), Changed>, - mut death_events: EventWriter, + mut death_events: MessageWriter, ) { for (entity, health) in query.iter() { if **health == 0. { @@ -33,35 +33,20 @@ impl Plugin for PacketPlugin { app.add_observer(game::handle_outgoing_packets_observer) .add_observer(config::handle_outgoing_packets_observer) .add_observer(login::handle_outgoing_packets_observer) - .add_systems( - Update, - ( - ( - config::handle_outgoing_packets, - game::handle_outgoing_packets, - login::handle_outgoing_packets, - ) - .chain(), - death_event_on_0_health.before(death_listener), - ), - ) - .add_event::() - .add_event::() - .add_event::() + .add_systems(Update, death_event_on_0_health.before(death_listener)) + .add_message::() + .add_message::() + .add_message::() // - .add_event::() - .add_event::() - .add_event::() - // - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::(); + .add_message::() + .add_message::() + .add_message::() + .add_message::() + .add_message::() + .add_message::() + .add_message::() + .add_message::() + .add_message::(); } } diff --git a/azalea-client/src/plugins/pong.rs b/azalea-client/src/plugins/pong.rs index e23b5245..f268a836 100644 --- a/azalea-client/src/plugins/pong.rs +++ b/azalea-client/src/plugins/pong.rs @@ -1,3 +1,4 @@ +use azalea_protocol::packets::{config, game}; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -22,16 +23,16 @@ impl Plugin for PongPlugin { } } -pub fn reply_to_game_ping(trigger: Trigger, mut commands: Commands) { +pub fn reply_to_game_ping(ping: On, mut commands: Commands) { commands.trigger(SendPacketEvent::new( - trigger.target(), - azalea_protocol::packets::game::ServerboundPong { id: trigger.0.id }, + ping.entity, + game::ServerboundPong { id: ping.packet.id }, )); } -pub fn reply_to_config_ping(trigger: Trigger, mut commands: Commands) { +pub fn reply_to_config_ping(ping: On, mut commands: Commands) { commands.trigger(SendConfigPacketEvent::new( - trigger.target(), - azalea_protocol::packets::config::ServerboundPong { id: trigger.0.id }, + ping.entity, + config::ServerboundPong { id: ping.packet.id }, )); } diff --git a/azalea-client/src/plugins/respawn.rs b/azalea-client/src/plugins/respawn.rs index f0ddd2b8..ecc773c4 100644 --- a/azalea-client/src/plugins/respawn.rs +++ b/azalea-client/src/plugins/respawn.rs @@ -5,7 +5,7 @@ use bevy_ecs::prelude::*; use crate::packet::game::SendPacketEvent; /// Tell the server that we're respawning. -#[derive(Event, Debug, Clone)] +#[derive(Message, Debug, Clone)] pub struct PerformRespawnEvent { pub entity: Entity, } @@ -14,12 +14,12 @@ pub struct PerformRespawnEvent { pub struct RespawnPlugin; impl Plugin for RespawnPlugin { fn build(&self, app: &mut App) { - app.add_event::() + app.add_message::() .add_systems(Update, perform_respawn); } } -pub fn perform_respawn(mut events: EventReader, mut commands: Commands) { +pub fn perform_respawn(mut events: MessageReader, mut commands: Commands) { for event in events.read() { commands.trigger(SendPacketEvent::new( event.entity, diff --git a/azalea-client/src/test_utils/simulation.rs b/azalea-client/src/test_utils/simulation.rs index 1fcc80b0..31461339 100644 --- a/azalea-client/src/test_utils/simulation.rs +++ b/azalea-client/src/test_utils/simulation.rs @@ -103,8 +103,11 @@ impl Simulation { raw_conn.injected_clientbound_packets.push(buf); }); } - pub fn send_event(&mut self, event: impl bevy_ecs::event::Event) { - self.app.world_mut().send_event(event); + pub fn write_message(&mut self, message: impl Message) { + self.app.world_mut().write_message(message); + } + pub fn trigger<'a>(&mut self, event: impl Event: Default>) { + self.app.world_mut().trigger(event); } pub fn tick(&mut self) { @@ -167,7 +170,7 @@ impl Simulation { pub fn disconnect(&mut self) { // send DisconnectEvent - self.app.world_mut().send_event(DisconnectEvent { + self.app.world_mut().write_message(DisconnectEvent { entity: self.entity, reason: None, }); @@ -188,12 +191,12 @@ impl SentPackets { let sent_packets_clone = sent_packets.clone(); simulation .app - .add_observer(move |trigger: Trigger| { - if trigger.sent_by == simulation_entity { + .add_observer(move |send_game_packet: On| { + if send_game_packet.sent_by == simulation_entity { sent_packets_clone .list .lock() - .push_back(trigger.event().packet.clone()) + .push_back(send_game_packet.packet.clone()) } }); diff --git a/azalea-client/tests/correct_movement.rs b/azalea-client/tests/correct_movement.rs index 52682bbb..5aaea9a3 100644 --- a/azalea-client/tests/correct_movement.rs +++ b/azalea-client/tests/correct_movement.rs @@ -49,7 +49,7 @@ fn test_correct_movement() { simulation.tick(); // walk for a tick - simulation.send_event(StartWalkEvent { + simulation.write_message(StartWalkEvent { entity: simulation.entity, direction: WalkDirection::Forward, }); diff --git a/azalea-client/tests/correct_sneak_movement.rs b/azalea-client/tests/correct_sneak_movement.rs index c486ac0a..0e06633a 100644 --- a/azalea-client/tests/correct_sneak_movement.rs +++ b/azalea-client/tests/correct_sneak_movement.rs @@ -62,7 +62,7 @@ fn test_correct_sneak_movement() { sent_packets.expect_empty(); simulation.tick(); - simulation.send_event(StartWalkEvent { + simulation.write_message(StartWalkEvent { entity: simulation.entity, direction: WalkDirection::Forward, }); diff --git a/azalea-client/tests/correct_sprint_sneak_movement.rs b/azalea-client/tests/correct_sprint_sneak_movement.rs index 10ff29ad..c76bc158 100644 --- a/azalea-client/tests/correct_sprint_sneak_movement.rs +++ b/azalea-client/tests/correct_sprint_sneak_movement.rs @@ -50,7 +50,7 @@ fn test_correct_sprint_sneak_movement() { sent_packets.clear(); // start sprinting - simulation.send_event(StartSprintEvent { + simulation.write_message(StartSprintEvent { entity: simulation.entity, direction: SprintDirection::Forward, }); diff --git a/azalea-client/tests/mine_block_rollback.rs b/azalea-client/tests/mine_block_rollback.rs index edbd1741..67a66169 100644 --- a/azalea-client/tests/mine_block_rollback.rs +++ b/azalea-client/tests/mine_block_rollback.rs @@ -27,7 +27,7 @@ fn test_mine_block_rollback() { assert_eq!(simulation.get_block_state(pos), Some(Block::Tnt.into())); println!("set serverside tnt"); - simulation.send_event(StartMiningBlockEvent { + simulation.write_message(StartMiningBlockEvent { entity: simulation.entity, position: pos, }); diff --git a/azalea-client/tests/mine_block_timing.rs b/azalea-client/tests/mine_block_timing.rs index 920f3a84..1cbd2f61 100644 --- a/azalea-client/tests/mine_block_timing.rs +++ b/azalea-client/tests/mine_block_timing.rs @@ -54,7 +54,7 @@ fn test_mine_block_timing() { simulation.tick(); simulation.tick(); - simulation.send_event(StartMiningBlockEvent { + simulation.write_message(StartMiningBlockEvent { entity: simulation.entity, position: pos, }); diff --git a/azalea-client/tests/mine_block_without_rollback.rs b/azalea-client/tests/mine_block_without_rollback.rs index cf6b5a5c..16a371e5 100644 --- a/azalea-client/tests/mine_block_without_rollback.rs +++ b/azalea-client/tests/mine_block_without_rollback.rs @@ -26,7 +26,7 @@ fn test_mine_block_without_rollback() { simulation.tick(); assert_eq!(simulation.get_block_state(pos), Some(Block::Tnt.into())); - simulation.send_event(StartMiningBlockEvent { + simulation.write_message(StartMiningBlockEvent { entity: simulation.entity, position: pos, }); diff --git a/azalea-client/tests/packet_order.rs b/azalea-client/tests/packet_order.rs index 1fd01934..90496292 100644 --- a/azalea-client/tests/packet_order.rs +++ b/azalea-client/tests/packet_order.rs @@ -109,7 +109,7 @@ fn test_packet_order() { sent_packets.expect_empty(); // now sprint for a tick - simulation.send_event(StartSprintEvent { + simulation.write_message(StartSprintEvent { entity: simulation.entity, direction: SprintDirection::Forward, }); diff --git a/azalea-client/tests/packet_order_set_carried_item.rs b/azalea-client/tests/packet_order_set_carried_item.rs index 18a75fc5..0506ad8e 100644 --- a/azalea-client/tests/packet_order_set_carried_item.rs +++ b/azalea-client/tests/packet_order_set_carried_item.rs @@ -55,11 +55,11 @@ fn test_packet_order_set_carried_item() { simulation.tick(); simulation.tick(); - simulation.send_event(SetSelectedHotbarSlotEvent { + simulation.write_message(SetSelectedHotbarSlotEvent { entity: simulation.entity, slot: 1, }); - simulation.send_event(StartMiningBlockEvent { + simulation.write_message(StartMiningBlockEvent { entity: simulation.entity, position: pos, }); diff --git a/azalea-client/tests/receive_start_config_packet.rs b/azalea-client/tests/receive_start_config_packet.rs index fb847769..bb948488 100644 --- a/azalea-client/tests/receive_start_config_packet.rs +++ b/azalea-client/tests/receive_start_config_packet.rs @@ -1,31 +1,20 @@ -use azalea_client::{InConfigState, packet::game::SendPacketEvent, test_utils::prelude::*}; +use azalea_client::{InConfigState, test_utils::prelude::*}; use azalea_protocol::packets::{ConnectionProtocol, game::ClientboundStartConfiguration}; use azalea_world::InstanceName; -use bevy_ecs::event::Events; #[test] fn test_receive_start_config_packet() { init_tracing(); let mut simulation = Simulation::new(ConnectionProtocol::Game); + simulation.receive_packet(default_login_packet()); simulation.tick(); assert!(simulation.has_component::()); simulation.tick(); - // we shouldn't be using the `SendPacketEvent` event directly, we should be - // using the trigger instead - simulation.with_resource_mut::>(|send_packet_events| { - assert_eq!(send_packet_events.len(), 0); - }); - simulation.receive_packet(ClientboundStartConfiguration); simulation.tick(); assert!(simulation.has_component::()); - - // check again just in case - simulation.with_resource_mut::>(|send_packet_events| { - assert_eq!(send_packet_events.len(), 0); - }); } diff --git a/azalea-client/tests/reply_to_ping_with_pong.rs b/azalea-client/tests/reply_to_ping_with_pong.rs index ac09336c..eac68e25 100644 --- a/azalea-client/tests/reply_to_ping_with_pong.rs +++ b/azalea-client/tests/reply_to_ping_with_pong.rs @@ -12,7 +12,7 @@ use azalea_protocol::packets::{ }, game::{self, ServerboundGamePacket}, }; -use bevy_ecs::observer::Trigger; +use bevy_ecs::observer::On; use parking_lot::Mutex; use simdnbt::owned::{NbtCompound, NbtTag}; @@ -26,9 +26,9 @@ fn reply_to_ping_with_pong() { let reply_count_clone = reply_count.clone(); simulation .app - .add_observer(move |trigger: Trigger| { - if trigger.sent_by == simulation.entity - && let ServerboundConfigPacket::Pong(packet) = &trigger.packet + .add_observer(move |send_config_packet: On| { + if send_config_packet.sent_by == simulation.entity + && let ServerboundConfigPacket::Pong(packet) = &send_config_packet.packet { assert_eq!(packet.id, 321); *reply_count_clone.lock() += 1; @@ -61,9 +61,9 @@ fn reply_to_ping_with_pong() { let reply_count_clone = reply_count.clone(); simulation .app - .add_observer(move |trigger: Trigger| { - if trigger.sent_by == simulation.entity - && let ServerboundGamePacket::Pong(packet) = &trigger.packet + .add_observer(move |send_game_packet: On| { + if send_game_packet.sent_by == simulation.entity + && let ServerboundGamePacket::Pong(packet) = &send_game_packet.packet { assert_eq!(packet.id, 123); *reply_count_clone.lock() += 1; diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs index 95fcb93f..e20ed860 100644 --- a/azalea-entity/src/plugin/mod.rs +++ b/azalea-entity/src/plugin/mod.rs @@ -25,7 +25,7 @@ use crate::{ /// A Bevy [`SystemSet`] for various types of entity updates. #[derive(SystemSet, Debug, Hash, Eq, PartialEq, Clone)] -pub enum EntityUpdateSet { +pub enum EntityUpdateSystems { /// Create search indexes for entities. Index, /// Remove despawned entities from search indexes. @@ -42,7 +42,7 @@ impl Plugin for EntityPlugin { // despawned post-update (done by this plugin) app.add_systems( PostUpdate, - indexing::remove_despawned_entities_from_indexes.in_set(EntityUpdateSet::Deindex), + indexing::remove_despawned_entities_from_indexes.in_set(EntityUpdateSystems::Deindex), ) .add_systems( Update, @@ -52,7 +52,7 @@ impl Plugin for EntityPlugin { indexing::insert_entity_chunk_position, ) .chain() - .in_set(EntityUpdateSet::Index), + .in_set(EntityUpdateSystems::Index), ( relative_updates::debug_detect_updates_received_on_local_entities, debug_new_entity, diff --git a/azalea/examples/nearest_entity.rs b/azalea/examples/nearest_entity.rs index 80bb544d..51aa26f6 100644 --- a/azalea/examples/nearest_entity.rs +++ b/azalea/examples/nearest_entity.rs @@ -12,7 +12,7 @@ use azalea_entity::{ }; use bevy_app::Plugin; use bevy_ecs::{ - prelude::{Entity, EventWriter}, + prelude::{Entity, MessageWriter}, query::With, system::Query, }; @@ -39,7 +39,7 @@ fn look_at_everything( bots: Query, With)>, entities: EntityFinder, entity_positions: Query<(&Position, Option<&EntityDimensions>)>, - mut look_at_event: EventWriter, + mut look_at_event: MessageWriter, ) { for bot_id in bots.iter() { let Some(entity) = entities.nearest_to_entity(bot_id, 16.0) else { diff --git a/azalea/examples/testbot/commands/debug.rs b/azalea/examples/testbot/commands/debug.rs index 3cdf4cf2..b98d737f 100644 --- a/azalea/examples/testbot/commands/debug.rs +++ b/azalea/examples/testbot/commands/debug.rs @@ -18,7 +18,7 @@ use azalea_entity::{EntityKindComponent, EntityUuid, metadata}; use azalea_inventory::components::MaxStackSize; use azalea_world::InstanceContainer; use bevy_app::AppExit; -use bevy_ecs::{event::Events, query::With}; +use bevy_ecs::{message::Messages, query::With, world::EntityRef}; use parking_lot::Mutex; use super::{CommandSource, Ctx}; @@ -246,21 +246,23 @@ pub fn register(commands: &mut CommandDispatcher>) { thread::sleep(Duration::from_secs(1)); // dump the ecs - let ecs = ecs.lock(); + let mut ecs = ecs.lock(); let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt"); let mut report = File::create(&report_path).unwrap(); - for entity in ecs.iter_entities() { + let mut query = ecs.query::(); + for entity in query.iter(& ecs) { writeln!(report, "Entity: {}", entity.id()).unwrap(); let archetype = entity.archetype(); let component_count = archetype.component_count(); let component_names = archetype .components() - .map(|c| ecs.components().get_info(c).unwrap().name()) + .iter() + .map(|c| ecs.components().get_info(*c).unwrap().name().to_string()) .collect::>(); writeln!( report, @@ -274,12 +276,12 @@ pub fn register(commands: &mut CommandDispatcher>) { for (info, _) in ecs.iter_resources() { - let name = info.name(); + let name = info.name().to_string(); writeln!(report, "Resource: {name}").unwrap(); // writeln!(report, "- Size: {} bytes", // info.layout().size()).unwrap(); - match name { + match name.as_ref() { "azalea_world::container::InstanceContainer" => { let instance_container = ecs.resource::(); @@ -311,12 +313,12 @@ pub fn register(commands: &mut CommandDispatcher>) { } } } - "bevy_ecs::event::collections::Events" => { - let events = ecs.resource::>(); + "bevy_ecs::message::Messages" => { + let events = ecs.resource::>(); writeln!(report, "- Event count: {}", events.len()).unwrap(); } - "bevy_ecs::event::collections::Events" => { - let events = ecs.resource::>(); + "bevy_ecs::message::Messages" => { + let events = ecs.resource::>(); writeln!(report, "- Event count: {}", events.len()).unwrap(); } @@ -340,7 +342,7 @@ pub fn register(commands: &mut CommandDispatcher>) { thread::spawn(move || { thread::sleep(Duration::from_secs(1)); - source.lock().bot.ecs.lock().send_event(AppExit::Success); + source.lock().bot.ecs.lock().write_message(AppExit::Success); }); 1 diff --git a/azalea/src/accept_resource_packs.rs b/azalea/src/accept_resource_packs.rs index f211f532..d67ada18 100644 --- a/azalea/src/accept_resource_packs.rs +++ b/azalea/src/accept_resource_packs.rs @@ -37,7 +37,7 @@ impl Plugin for AcceptResourcePacksPlugin { } fn accept_resource_pack( - mut events: EventReader, + mut events: MessageReader, mut commands: Commands, query_in_config_state: Query>, ) { diff --git a/azalea/src/auto_respawn.rs b/azalea/src/auto_respawn.rs index 6e970a71..1b74418f 100644 --- a/azalea/src/auto_respawn.rs +++ b/azalea/src/auto_respawn.rs @@ -22,8 +22,8 @@ impl Plugin for AutoRespawnPlugin { } fn auto_respawn( - mut events: EventReader, - mut perform_respawn_events: EventWriter, + mut events: MessageReader, + mut perform_respawn_events: MessageWriter, ) { for event in events.read() { perform_respawn_events.write(PerformRespawnEvent { diff --git a/azalea/src/auto_tool.rs b/azalea/src/auto_tool.rs index 3d8d6e36..e7eb614d 100644 --- a/azalea/src/auto_tool.rs +++ b/azalea/src/auto_tool.rs @@ -19,12 +19,12 @@ pub trait AutoToolClientExt { impl AutoToolClientExt for Client { fn best_tool_in_hotbar_for_block(&self, block: BlockState) -> BestToolResult { - let mut ecs = self.ecs.lock(); - let (inventory, physics, fluid_on_eyes) = - self.query::<(&Inventory, &Physics, &FluidOnEyes)>(&mut ecs); - let menu = &inventory.inventory_menu; - - accurate_best_tool_in_hotbar_for_block(block, menu, physics, fluid_on_eyes) + self.query_self::<(&Inventory, &Physics, &FluidOnEyes), _>( + |(inventory, physics, fluid_on_eyes)| { + let menu = &inventory.inventory_menu; + accurate_best_tool_in_hotbar_for_block(block, menu, physics, fluid_on_eyes) + }, + ) } async fn mine_with_auto_tool(&self, block_pos: BlockPos) { diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs index b037ed14..5523b7b2 100644 --- a/azalea/src/bot.rs +++ b/azalea/src/bot.rs @@ -26,7 +26,6 @@ use crate::{ ecs::{ component::Component, entity::Entity, - event::EventReader, query::{With, Without}, system::{Commands, Query}, }, @@ -37,8 +36,8 @@ use crate::{ pub struct BotPlugin; impl Plugin for BotPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() + app.add_message::() + .add_message::() .add_systems( Update, ( @@ -108,14 +107,14 @@ pub trait BotClientExt { impl BotClientExt for azalea_client::Client { fn jump(&self) { let mut ecs = self.ecs.lock(); - ecs.send_event(JumpEvent { + ecs.write_message(JumpEvent { entity: self.entity, }); } fn look_at(&self, position: Vec3) { let mut ecs = self.ecs.lock(); - ecs.send_event(LookAtEvent { + ecs.write_message(LookAtEvent { entity: self.entity, position, }); @@ -200,14 +199,14 @@ impl BotClientExt for azalea_client::Client { } /// Event to jump once. -#[derive(Event)] +#[derive(Message)] pub struct JumpEvent { pub entity: Entity, } pub fn jump_listener( mut query: Query<(&mut Jumping, &mut Bot)>, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let Ok((mut jumping, mut bot)) = query.get_mut(event.entity) { @@ -218,14 +217,14 @@ pub fn jump_listener( } /// Make an entity look towards a certain position in the world. -#[derive(Event)] +#[derive(Message)] pub struct LookAtEvent { pub entity: Entity, /// The position we want the entity to be looking at. pub position: Vec3, } fn look_at_listener( - mut events: EventReader, + mut events: MessageReader, mut query: Query<(&Position, &EntityDimensions, &mut LookDirection)>, ) { for event in events.read() { diff --git a/azalea/src/container.rs b/azalea/src/container.rs index b3e3bb65..cd11b7c2 100644 --- a/azalea/src/container.rs +++ b/azalea/src/container.rs @@ -13,7 +13,7 @@ use azalea_inventory::{ use azalea_physics::collision::BlockWithShape; use azalea_protocol::packets::game::ClientboundGamePacket; use bevy_app::{App, Plugin, Update}; -use bevy_ecs::{component::Component, prelude::EventReader, system::Commands}; +use bevy_ecs::{component::Component, prelude::MessageReader, system::Commands}; use derive_more::Deref; use futures_lite::Future; @@ -126,14 +126,11 @@ impl ContainerClientExt for Client { } fn get_inventory(&self) -> ContainerHandleRef { - let ecs = self.ecs.lock(); - let inventory = ecs.get::(self.entity).expect("no inventory"); - ContainerHandleRef::new(inventory.id, self.clone()) + self.query_self::<&Inventory, _>(|inv| ContainerHandleRef::new(inv.id, self.clone())) } fn get_held_item(&self) -> ItemStack { - self.map_get_component::(|inventory| inventory.held_item()) - .expect("no inventory") + self.query_self::<&Inventory, _>(|inv| inv.held_item()) } } @@ -156,7 +153,7 @@ impl ContainerHandleRef { } pub fn close(&self) { - self.client.ecs.lock().send_event(CloseContainerEvent { + self.client.ecs.lock().trigger(CloseContainerEvent { entity: self.client.entity, id: self.id, }); @@ -228,7 +225,7 @@ impl ContainerHandleRef { /// action. pub fn click(&self, operation: impl Into) { let operation = operation.into(); - self.client.ecs.lock().send_event(ContainerClickEvent { + self.client.ecs.lock().trigger(ContainerClickEvent { entity: self.client.entity, window_id: self.id, operation, @@ -269,7 +266,7 @@ pub struct WaitingForInventoryOpen; pub fn handle_menu_opened_event( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, ) { for event in events.read() { if let ClientboundGamePacket::ContainerSetContent { .. } = event.packet.as_ref() { diff --git a/azalea/src/nearest_entity.rs b/azalea/src/nearest_entity.rs index df54273a..2c01e5df 100644 --- a/azalea/src/nearest_entity.rs +++ b/azalea/src/nearest_entity.rs @@ -21,7 +21,7 @@ use bevy_ecs::{ /// metadata::{AbstractMonster, Player}, /// }; /// use bevy_ecs::{ -/// prelude::{Entity, EventWriter}, +/// prelude::{Entity, MessageWriter}, /// query::With, /// system::Query, /// }; @@ -30,7 +30,7 @@ use bevy_ecs::{ /// pub fn bots_near_aggressive_mobs( /// bots: Query, With)>, /// entity_finder: EntityFinder>, -/// mut chat_events: EventWriter, +/// mut chat_events: MessageWriter, /// ) { /// for bot_id in bots.iter() { /// let Some(nearest) = entity_finder.nearest_to_entity(bot_id, 16.0) else { diff --git a/azalea/src/pathfinder/debug.rs b/azalea/src/pathfinder/debug.rs index d0d264d3..4b241e5d 100644 --- a/azalea/src/pathfinder/debug.rs +++ b/azalea/src/pathfinder/debug.rs @@ -37,8 +37,8 @@ pub struct PathfinderDebugParticles; pub fn debug_render_path_with_particles( mut query: Query<(Entity, &ExecutingPath, &InstanceHolder), With>, // chat_events is Option because the tests don't have SendChatEvent - // and we have to use ResMut because bevy doesn't support Option - chat_events: Option>>, + // and we have to use ResMut because bevy doesn't support Option + chat_events: Option>>, mut tick_count: Local, ) { let Some(mut chat_events) = chat_events else { @@ -104,7 +104,7 @@ pub fn debug_render_path_with_particles( delta_z = 0, count = 1 ); - chat_events.send(SendChatEvent { + chat_events.write(SendChatEvent { entity, content: particle_command, }); diff --git a/azalea/src/pathfinder/goto_event.rs b/azalea/src/pathfinder/goto_event.rs index bd0e1540..379c61d0 100644 --- a/azalea/src/pathfinder/goto_event.rs +++ b/azalea/src/pathfinder/goto_event.rs @@ -1,6 +1,6 @@ use std::{sync::Arc, time::Duration}; -use bevy_ecs::{entity::Entity, event::Event}; +use bevy_ecs::prelude::*; use crate::pathfinder::{ astar::PathfinderTimeout, @@ -16,7 +16,7 @@ use crate::pathfinder::{ /// /// [`goto_listener`]: crate::pathfinder::goto_listener /// [`PathfinderClientExt::goto`]: crate::pathfinder::PathfinderClientExt::goto -#[derive(Event)] +#[derive(Message)] #[non_exhaustive] pub struct GotoEvent { /// The local bot entity that will do the pathfinding and execute the path. diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 6fbf0de4..118a13ee 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -68,7 +68,6 @@ use crate::{ ecs::{ component::Component, entity::Entity, - event::{EventReader, EventWriter}, query::{With, Without}, system::{Commands, Query, Res}, }, @@ -79,9 +78,9 @@ use crate::{ pub struct PathfinderPlugin; impl Plugin for PathfinderPlugin { fn build(&self, app: &mut App) { - app.add_event::() - .add_event::() - .add_event::() + app.add_message::() + .add_message::() + .add_message::() .add_systems( // putting systems in the GameTick schedule makes them run every Minecraft tick // (every 50 milliseconds). @@ -138,7 +137,7 @@ pub struct ExecutingPath { pub is_path_partial: bool, } -#[derive(Event, Clone, Debug)] +#[derive(Message, Clone, Debug)] #[non_exhaustive] pub struct PathFoundEvent { pub entity: Entity, @@ -240,16 +239,16 @@ impl PathfinderClientExt for azalea_client::Client { fn start_goto_with_opts(&self, goal: impl Goal + 'static, opts: PathfinderOpts) { self.ecs .lock() - .send_event(GotoEvent::new(self.entity, goal, opts)); + .write_message(GotoEvent::new(self.entity, goal, opts)); } fn stop_pathfinding(&self) { - self.ecs.lock().send_event(StopPathfindingEvent { + self.ecs.lock().write_message(StopPathfindingEvent { entity: self.entity, force: false, }); } fn force_stop_pathfinding(&self) { - self.ecs.lock().send_event(StopPathfindingEvent { + self.ecs.lock().write_message(StopPathfindingEvent { entity: self.entity, force: true, }); @@ -270,8 +269,10 @@ impl PathfinderClientExt for azalea_client::Client { } } fn is_goto_target_reached(&self) -> bool { - self.map_get_component::(|p| p.goal.is_none() && !p.is_calculating) - .unwrap_or(true) + self.query_self::, _>(|p| { + p.map(|p| p.goal.is_none() && !p.is_calculating) + .unwrap_or(true) + }) } } @@ -281,7 +282,7 @@ pub struct ComputePath(Task>); #[allow(clippy::type_complexity)] pub fn goto_listener( mut commands: Commands, - mut events: EventReader, + mut events: MessageReader, mut query: Query<( &mut Pathfinder, Option<&ExecutingPath>, @@ -499,7 +500,7 @@ pub fn calculate_path(ctx: CalculatePathCtx) -> Option { pub fn handle_tasks( mut commands: Commands, mut transform_tasks: Query<(Entity, &mut ComputePath)>, - mut path_found_events: EventWriter, + mut path_found_events: MessageWriter, ) { for (entity, mut task) in &mut transform_tasks { if let Some(optional_path_found_event) = future::block_on(future::poll_once(&mut task.0)) { @@ -516,7 +517,7 @@ pub fn handle_tasks( // set the path for the target entity when we get the PathFoundEvent #[allow(clippy::type_complexity)] pub fn path_found_listener( - mut events: EventReader, + mut events: MessageReader, mut query: Query<( &mut Pathfinder, Option<&mut ExecutingPath>, @@ -709,7 +710,7 @@ pub fn check_node_reached( &Position, &Physics, )>, - mut walk_events: EventWriter, + mut walk_events: MessageWriter, mut commands: Commands, ) { for (entity, mut pathfinder, mut executing_path, position, physics) in &mut query { @@ -991,8 +992,8 @@ fn patch_path( pub fn recalculate_near_end_of_path( mut query: Query<(Entity, &mut Pathfinder, &mut ExecutingPath)>, - mut walk_events: EventWriter, - mut goto_events: EventWriter, + mut walk_events: MessageWriter, + mut goto_events: MessageWriter, mut commands: Commands, ) { for (entity, mut pathfinder, mut executing_path) in &mut query { @@ -1072,12 +1073,12 @@ pub fn tick_execute_path( &InstanceHolder, &Inventory, )>, - mut look_at_events: EventWriter, - mut sprint_events: EventWriter, - mut walk_events: EventWriter, - mut jump_events: EventWriter, - mut start_mining_events: EventWriter, - mut set_selected_hotbar_slot_events: EventWriter, + mut look_at_events: MessageWriter, + mut sprint_events: MessageWriter, + mut walk_events: MessageWriter, + mut jump_events: MessageWriter, + mut start_mining_events: MessageWriter, + mut set_selected_hotbar_slot_events: MessageWriter, ) { for (entity, executing_path, position, physics, mining, instance_holder, inventory_component) in &mut query @@ -1111,7 +1112,7 @@ pub fn tick_execute_path( pub fn recalculate_if_has_goal_but_no_path( mut query: Query<(Entity, &mut Pathfinder), Without>, - mut goto_events: EventWriter, + mut goto_events: MessageWriter, ) { for (entity, mut pathfinder) in &mut query { if pathfinder.goal.is_some() @@ -1126,7 +1127,7 @@ pub fn recalculate_if_has_goal_but_no_path( } } -#[derive(Event)] +#[derive(Message)] pub struct StopPathfindingEvent { pub entity: Entity, /// If false, then let the current movement finish before stopping. If true, @@ -1136,9 +1137,9 @@ pub struct StopPathfindingEvent { } pub fn handle_stop_pathfinding_event( - mut events: EventReader, + mut events: MessageReader, mut query: Query<(&mut Pathfinder, &mut ExecutingPath)>, - mut walk_events: EventWriter, + mut walk_events: MessageWriter, mut commands: Commands, ) { for event in events.read() { @@ -1171,7 +1172,7 @@ pub fn handle_stop_pathfinding_event( pub fn stop_pathfinding_on_instance_change( mut query: Query<(Entity, &mut ExecutingPath), Changed>, - mut stop_pathfinding_events: EventWriter, + mut stop_pathfinding_events: MessageWriter, ) { for (entity, mut executing_path) in &mut query { if !executing_path.path.is_empty() { diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs index 3111516d..1e22f683 100644 --- a/azalea/src/pathfinder/moves/mod.rs +++ b/azalea/src/pathfinder/moves/mod.rs @@ -14,7 +14,7 @@ use azalea_client::{ use azalea_core::position::{BlockPos, Vec3}; use azalea_inventory::Menu; use azalea_world::Instance; -use bevy_ecs::{entity::Entity, event::EventWriter}; +use bevy_ecs::{entity::Entity, message::MessageWriter}; use parking_lot::RwLock; use super::{ @@ -66,12 +66,12 @@ pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'w5, 'w6, 'a> { pub instance: Arc>, pub menu: Menu, - pub look_at_events: &'a mut EventWriter<'w1, LookAtEvent>, - pub sprint_events: &'a mut EventWriter<'w2, StartSprintEvent>, - pub walk_events: &'a mut EventWriter<'w3, StartWalkEvent>, - pub jump_events: &'a mut EventWriter<'w4, JumpEvent>, - pub start_mining_events: &'a mut EventWriter<'w5, StartMiningBlockEvent>, - pub set_selected_hotbar_slot_events: &'a mut EventWriter<'w6, SetSelectedHotbarSlotEvent>, + pub look_at_events: &'a mut MessageWriter<'w1, LookAtEvent>, + pub sprint_events: &'a mut MessageWriter<'w2, StartSprintEvent>, + pub walk_events: &'a mut MessageWriter<'w3, StartWalkEvent>, + pub jump_events: &'a mut MessageWriter<'w4, JumpEvent>, + pub start_mining_events: &'a mut MessageWriter<'w5, StartMiningBlockEvent>, + pub set_selected_hotbar_slot_events: &'a mut MessageWriter<'w6, SetSelectedHotbarSlotEvent>, } impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_> { diff --git a/azalea/src/pathfinder/simulation.rs b/azalea/src/pathfinder/simulation.rs index 78de1642..94836d3b 100644 --- a/azalea/src/pathfinder/simulation.rs +++ b/azalea/src/pathfinder/simulation.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use azalea_client::{ PhysicsState, interact::BlockStatePredictionHandler, inventory::Inventory, - local_player::LocalGameMode, mining::MineBundle, packet::game::SendPacketEvent, + local_player::LocalGameMode, mining::MineBundle, }; use azalea_core::{ game_type::GameMode, position::Vec3, resource_location::ResourceLocation, tick::GameTick, @@ -76,8 +76,7 @@ fn create_simulation_instance(chunks: ChunkStorage) -> (App, Arc(); + }); app.edit_schedule(bevy_app::Main, |schedule| { schedule.set_executor_kind(bevy_ecs::schedule::ExecutorKind::SingleThreaded); diff --git a/azalea/src/pathfinder/tests.rs b/azalea/src/pathfinder/tests.rs index 4f9d2296..7b33ca18 100644 --- a/azalea/src/pathfinder/tests.rs +++ b/azalea/src/pathfinder/tests.rs @@ -33,7 +33,7 @@ fn setup_blockposgoal_simulation( // ..Default::default() // }); - simulation.app.world_mut().send_event(GotoEvent { + simulation.app.world_mut().write_message(GotoEvent { entity: simulation.entity, goal: Arc::new(BlockPosGoal(end_pos)), opts: PathfinderOpts { @@ -299,7 +299,7 @@ fn test_mine_through_non_colliding_block() { ], ); - simulation.app.world_mut().send_event(GotoEvent { + simulation.app.world_mut().write_message(GotoEvent { entity: simulation.entity, goal: Arc::new(BlockPosGoal(BlockPos::new(0, 69, 0))), opts: PathfinderOpts::new() diff --git a/azalea/src/swarm/chat.rs b/azalea/src/swarm/chat.rs index 21db2fd8..46741be6 100644 --- a/azalea/src/swarm/chat.rs +++ b/azalea/src/swarm/chat.rs @@ -17,7 +17,6 @@ use std::collections::VecDeque; use azalea_client::chat::{ChatPacket, ChatReceivedEvent}; use bevy_app::{App, Plugin, Update}; -use bevy_ecs::prelude::Event; use super::{Swarm, SwarmEvent}; use crate::ecs::prelude::*; @@ -26,7 +25,7 @@ use crate::ecs::prelude::*; pub struct SwarmChatPlugin; impl Plugin for SwarmChatPlugin { fn build(&self, app: &mut App) { - app.add_event::() + app.add_message::() .add_systems( Update, (chat_listener, update_min_index_and_shrink_queue).chain(), @@ -44,7 +43,7 @@ pub struct ClientChatState { } /// A chat message that no other bots have seen yet was received by a bot. -#[derive(Event, Debug)] +#[derive(Message, Debug)] pub struct NewChatMessageEvent(ChatPacket); #[derive(Resource)] @@ -56,9 +55,9 @@ pub struct GlobalChatState { fn chat_listener( mut commands: Commands, mut query: Query<&mut ClientChatState>, - mut events: EventReader, + mut events: MessageReader, mut global_chat_state: ResMut, - mut new_chat_messages_events: EventWriter, + mut new_chat_messages_events: MessageWriter, ) { for event in events.read() { let mut client_chat_state = query.get_mut(event.entity); @@ -112,7 +111,7 @@ fn chat_listener( fn update_min_index_and_shrink_queue( query: Query<&ClientChatState>, mut global_chat_state: ResMut, - mut events: EventReader, + mut events: MessageReader, swarm: Option>, ) { for event in events.read() { @@ -150,16 +149,16 @@ fn update_min_index_and_shrink_queue( #[cfg(test)] mod tests { - use bevy_ecs::{event::Events, prelude::World, system::SystemState}; + use bevy_ecs::{prelude::World, system::SystemState}; use super::*; fn make_test_app() -> App { let mut app = App::new(); - // we add the events like this instead of with .add_event so we can have our own - // event management in drain_events - app.init_resource::>() - .init_resource::>() + // we add the events like this instead of with .add_message so we can have our + // own event management in drain_messages + app.init_resource::>() + .init_resource::>() .add_systems( Update, (chat_listener, update_min_index_and_shrink_queue).chain(), @@ -171,12 +170,12 @@ mod tests { app } - fn drain_events(ecs: &mut World) -> Vec { - let mut system_state: SystemState>> = + fn drain_messages(ecs: &mut World) -> Vec { + let mut system_state: SystemState>> = SystemState::new(ecs); - let mut events = system_state.get_mut(ecs); + let mut messages = system_state.get_mut(ecs); - events.drain().map(|e| e.0.clone()).collect::>() + messages.drain().map(|e| e.0.clone()).collect::>() } #[tokio::test] @@ -186,46 +185,46 @@ mod tests { let bot0 = app.world_mut().spawn_empty().id(); let bot1 = app.world_mut().spawn_empty().id(); - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot0, packet: ChatPacket::new("a"), }); app.update(); // the swarm should get the event immediately after the bot gets it - assert_eq!(drain_events(app.world_mut()), vec![ChatPacket::new("a")]); + assert_eq!(drain_messages(app.world_mut()), vec![ChatPacket::new("a")]); assert_eq!( app.world().get::(bot0).unwrap().chat_index, 1 ); // and a second bot sending the event shouldn't do anything - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot1, packet: ChatPacket::new("a"), }); app.update(); - assert_eq!(drain_events(app.world_mut()), vec![]); + assert_eq!(drain_messages(app.world_mut()), vec![]); assert_eq!( app.world().get::(bot1).unwrap().chat_index, 1 ); // but if the first one gets it again, it should sent it again - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot0, packet: ChatPacket::new("a"), }); app.update(); - assert_eq!(drain_events(app.world_mut()), vec![ChatPacket::new("a")]); + assert_eq!(drain_messages(app.world_mut()), vec![ChatPacket::new("a")]); // alright and now the second bot got a different chat message and it should be // sent - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot1, packet: ChatPacket::new("b"), }); app.update(); - assert_eq!(drain_events(app.world_mut()), vec![ChatPacket::new("b")]); + assert_eq!(drain_messages(app.world_mut()), vec![ChatPacket::new("b")]); } #[tokio::test] @@ -235,18 +234,18 @@ mod tests { let bot0 = app.world_mut().spawn_empty().id(); // bot0 gets a chat message - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot0, packet: ChatPacket::new("a"), }); app.update(); - assert_eq!(drain_events(app.world_mut()), vec![ChatPacket::new("a")]); + assert_eq!(drain_messages(app.world_mut()), vec![ChatPacket::new("a")]); let bot1 = app.world_mut().spawn_empty().id(); - app.world_mut().send_event(ChatReceivedEvent { + app.world_mut().write_message(ChatReceivedEvent { entity: bot1, packet: ChatPacket::new("b"), }); app.update(); - assert_eq!(drain_events(app.world_mut()), vec![ChatPacket::new("b")]); + assert_eq!(drain_messages(app.world_mut()), vec![ChatPacket::new("b")]); } } diff --git a/azalea/src/swarm/events.rs b/azalea/src/swarm/events.rs index aff578a3..78fb6127 100644 --- a/azalea/src/swarm/events.rs +++ b/azalea/src/swarm/events.rs @@ -7,14 +7,14 @@ use derive_more::{Deref, DerefMut}; pub struct SwarmPlugin; impl Plugin for SwarmPlugin { fn build(&self, app: &mut App) { - app.add_event::() + app.add_message::() .add_systems(Update, check_ready) .init_resource::(); } } /// All the bots from the swarm are now in the world. -#[derive(Event)] +#[derive(Message)] pub struct SwarmReadyEvent; #[derive(Default, Resource, Deref, DerefMut)] @@ -23,7 +23,7 @@ struct IsSwarmReady(bool); fn check_ready( query: Query, With>, mut is_swarm_ready: ResMut, - mut ready_events: EventWriter, + mut ready_events: MessageWriter, ) { // if we already know the swarm is ready, do nothing if **is_swarm_ready { -- cgit v1.2.3