aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--Cargo.lock292
-rw-r--r--Cargo.toml12
-rw-r--r--azalea-client/src/client.rs75
-rw-r--r--azalea-client/src/entity_query.rs31
-rw-r--r--azalea-client/src/player.rs4
-rw-r--r--azalea-client/src/plugins/attack.rs8
-rw-r--r--azalea-client/src/plugins/auto_reconnect.rs6
-rw-r--r--azalea-client/src/plugins/chat/handler.rs4
-rw-r--r--azalea-client/src/plugins/chat/mod.rs20
-rw-r--r--azalea-client/src/plugins/chunks.rs18
-rw-r--r--azalea-client/src/plugins/client_information.rs8
-rw-r--r--azalea-client/src/plugins/connection.rs10
-rw-r--r--azalea-client/src/plugins/disconnect.rs8
-rw-r--r--azalea-client/src/plugins/events.rs23
-rw-r--r--azalea-client/src/plugins/interact/mod.rs23
-rw-r--r--azalea-client/src/plugins/inventory.rs213
-rw-r--r--azalea-client/src/plugins/join.rs12
-rw-r--r--azalea-client/src/plugins/login.rs10
-rw-r--r--azalea-client/src/plugins/mining.rs79
-rw-r--r--azalea-client/src/plugins/movement.rs41
-rw-r--r--azalea-client/src/plugins/packet/config/events.rs33
-rw-r--r--azalea-client/src/plugins/packet/config/mod.rs11
-rw-r--r--azalea-client/src/plugins/packet/game/events.rs48
-rw-r--r--azalea-client/src/plugins/packet/game/mod.rs39
-rw-r--r--azalea-client/src/plugins/packet/login/events.rs22
-rw-r--r--azalea-client/src/plugins/packet/login/mod.rs16
-rw-r--r--azalea-client/src/plugins/packet/mod.rs43
-rw-r--r--azalea-client/src/plugins/pong.rs13
-rw-r--r--azalea-client/src/plugins/respawn.rs6
-rw-r--r--azalea-client/src/test_utils/simulation.rs15
-rw-r--r--azalea-client/tests/correct_movement.rs2
-rw-r--r--azalea-client/tests/correct_sneak_movement.rs2
-rw-r--r--azalea-client/tests/correct_sprint_sneak_movement.rs2
-rw-r--r--azalea-client/tests/mine_block_rollback.rs2
-rw-r--r--azalea-client/tests/mine_block_timing.rs2
-rw-r--r--azalea-client/tests/mine_block_without_rollback.rs2
-rw-r--r--azalea-client/tests/packet_order.rs2
-rw-r--r--azalea-client/tests/packet_order_set_carried_item.rs4
-rw-r--r--azalea-client/tests/receive_start_config_packet.rs15
-rw-r--r--azalea-client/tests/reply_to_ping_with_pong.rs14
-rw-r--r--azalea-entity/src/plugin/mod.rs6
-rw-r--r--azalea/examples/nearest_entity.rs4
-rw-r--r--azalea/examples/testbot/commands/debug.rs24
-rw-r--r--azalea/src/accept_resource_packs.rs2
-rw-r--r--azalea/src/auto_respawn.rs4
-rw-r--r--azalea/src/auto_tool.rs12
-rw-r--r--azalea/src/bot.rs17
-rw-r--r--azalea/src/container.rs15
-rw-r--r--azalea/src/nearest_entity.rs4
-rw-r--r--azalea/src/pathfinder/debug.rs6
-rw-r--r--azalea/src/pathfinder/goto_event.rs4
-rw-r--r--azalea/src/pathfinder/mod.rs55
-rw-r--r--azalea/src/pathfinder/moves/mod.rs14
-rw-r--r--azalea/src/pathfinder/simulation.rs5
-rw-r--r--azalea/src/pathfinder/tests.rs4
-rw-r--r--azalea/src/swarm/chat.rs53
-rw-r--r--azalea/src/swarm/events.rs6
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,35 +804,16 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -864,6 +847,26 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -901,15 +904,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -978,17 +972,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1248,32 +1231,11 @@ dependencies = [
[[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,20 +1582,14 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1653,21 +1610,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1955,7 +1906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
- "hashbrown 0.16.0",
+ "hashbrown",
]
[[package]]
@@ -2074,16 +2025,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2158,12 +2099,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2220,16 +2155,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2535,16 +2460,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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",
@@ -2837,12 +2752,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
@@ -3105,6 +3014,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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::<Entity>();
- 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<R>(&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<R>(&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::<InstanceName>();
/// # }
pub fn component<T: Component + Clone>(&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<T: Component + Clone>(&self) -> Option<T> {
- self.query::<Option<&T>>(&mut self.ecs.lock()).cloned()
+ self.query_self::<Option<&T>, _>(|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::<Hunger, _>(|h| h.food);
- /// # }
- /// ```
- pub fn map_component<T: Component, R>(&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<T: Component, R>(&self, f: impl FnOnce(&T) -> R) -> Option<R> {
- let mut ecs = self.ecs.lock();
- let value = self.query::<Option<&T>>(&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::<Option<&InstanceName>>(&mut self.ecs.lock())
- .is_some()
+ self.query_self::<Option<&InstanceName>, _>(|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<MinecraftEntityId> {
- self.map_component::<EntityIdIndex, _>(|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<Entity> {
- self.map_component::<EntityIdIndex, _>(|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<AppExit> {
- let mut reader = EventCursor::default();
+ let mut reader = MessageCursor::default();
- let events = ecs.get_resource::<Events<AppExit>>()?;
+ let events = ecs.get_resource::<Messages<AppExit>>()?;
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::<Option<&InstanceName>>(&mut client.ecs.lock())
- /// .is_some();
+ /// let is_logged_in = client.query_self::<Option<&InstanceName>, _>(|ins| ins.is_some());
/// # }
/// ```
- pub fn query<'w, D: QueryData>(&self, ecs: &'w mut World) -> D::Item<'w> {
- ecs.query::<D>()
- .get_mut(ecs, self.entity)
- .unwrap_or_else(|_| {
- panic!(
- "Our client is missing a required component {:?}",
- any::type_name::<D>()
- )
- })
+ ///
+ /// # Panics
+ ///
+ /// This will panic if the component doesn't exist on the client.
+ pub fn query_self<D: QueryData, R>(&self, f: impl FnOnce(QueryItem<D>) -> R) -> R {
+ let mut ecs = self.ecs.lock();
+ let mut qs = ecs.query::<D>();
+ let res = qs.get_mut(&mut ecs, self.entity).unwrap_or_else(|_| {
+ panic!(
+ "Our client is missing a required component {:?}",
+ any::type_name::<D>()
+ )
+ });
+ 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<AddPlayerEvent>,
+ mut events: MessageReader<AddPlayerEvent>,
entity_uuid_index: Res<EntityUuidIndex>,
) {
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::<AttackEvent>()
+ app.add_message::<AttackEvent>()
.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<AttackEvent>, mut commands: Commands) {
+pub fn handle_attack_event(mut events: MessageReader<AttackEvent>, 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<DisconnectEvent>,
- mut connection_failed_events: EventReader<ConnectionFailedEvent>,
+ mut disconnect_events: MessageReader<DisconnectEvent>,
+ mut connection_failed_events: MessageReader<ConnectionFailedEvent>,
auto_reconnect_delay_res: Option<Res<AutoReconnectDelay>>,
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<StartJoinServerEvent>,
+ mut join_events: MessageWriter<StartJoinServerEvent>,
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<SendChatKindEvent>,
+ mut events: MessageReader<SendChatKindEvent>,
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::<SendChatEvent>()
- .add_event::<SendChatKindEvent>()
- .add_event::<ChatReceivedEvent>()
+ app.add_message::<SendChatEvent>()
+ .add_message::<SendChatKindEvent>()
+ .add_message::<ChatReceivedEvent>()
.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<String>) {
- 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<SendChatEvent>,
- mut send_chat_kind_events: EventWriter<SendChatKindEvent>,
+ mut events: MessageReader<SendChatEvent>,
+ mut send_chat_kind_events: MessageWriter<SendChatKindEvent>,
) {
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::<ReceiveChunkEvent>()
- .add_event::<ChunkBatchStartEvent>()
- .add_event::<ChunkBatchFinishedEvent>();
+ .add_message::<ReceiveChunkEvent>()
+ .add_message::<ChunkBatchStartEvent>()
+ .add_message::<ChunkBatchFinishedEvent>();
}
}
-#[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<ReceiveChunkEvent>,
+ mut events: MessageReader<ReceiveChunkEvent>,
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<ChunkBatchStartEvent>,
+ mut events: MessageReader<ChunkBatchStartEvent>,
) {
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<ChunkBatchFinishedEvent>,
+ mut events: MessageReader<ChunkBatchFinishedEvent>,
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<ReceiveGamePacketEvent>,
}
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::<DisconnectEvent>().add_systems(
+ app.add_message::<DisconnectEvent>().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<FormattedText>,
@@ -82,7 +82,7 @@ pub struct RemoveOnDisconnectBundle {
/// a [`DisconnectEvent`].
pub fn remove_components_from_disconnected_players(
mut commands: Commands,
- mut events: EventReader<DisconnectEvent>,
+ mut events: MessageReader<DisconnectEvent>,
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<IsConnectionAlive>, With<LocalEntity>)>,
- mut disconnect_events: EventWriter<DisconnectEvent>,
+ mut disconnect_events: MessageWriter<DisconnectEvent>,
) {
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<ThingEvent>.
+// - To get the event writer, you have to get an MessageWriter<ThingEvent>.
// 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<ChatReceivedEvent>) {
+pub fn chat_listener(
+ query: Query<&LocalPlayerEvents>,
+ mut events: MessageReader<ChatReceivedEvent>,
+) {
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<InstanceName>>) {
#[cfg(feature = "packet-event")]
pub fn packet_listener(
query: Query<&LocalPlayerEvents>,
- mut events: EventReader<super::packet::game::ReceiveGamePacketEvent>,
+ mut events: MessageReader<super::packet::game::ReceiveGamePacketEvent>,
) {
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<AddPlayerEvent>,
+ mut events: MessageReader<AddPlayerEvent>,
) {
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<UpdatePlayerEvent>,
+ mut events: MessageReader<UpdatePlayerEvent>,
) {
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<RemovePlayerEvent>,
+ mut events: MessageReader<RemovePlayerEvent>,
) {
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<DeathEvent>) {
+pub fn death_listener(query: Query<&LocalPlayerEvents>, mut events: MessageReader<DeathEvent>) {
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<Dead>>) {
pub fn keepalive_listener(
query: Query<&LocalPlayerEvents>,
- mut events: EventReader<KeepAliveEvent>,
+ mut events: MessageReader<KeepAliveEvent>,
) {
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<DisconnectEvent>,
+ mut events: MessageReader<DisconnectEvent>,
) {
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<ReceiveChunkEvent>,
+ mut events: MessageReader<ReceiveChunkEvent>,
) {
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::<StartUseItemEvent>()
- .add_event::<SwingArmEvent>()
+ app.add_message::<StartUseItemEvent>()
.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<StartUseItemEvent>,
+ mut events: MessageReader<StartUseItemEvent>,
) {
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<SwingArmEvent>, mut commands: Commands) {
+pub fn handle_swing_arm_trigger(swing_arm: On<SwingArmEvent>, 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<SwingArmEvent>, 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::<ClientsideCloseContainerEvent>()
- .add_event::<MenuOpenedEvent>()
- .add_event::<CloseContainerEvent>()
- .add_event::<ContainerClickEvent>()
- .add_event::<SetContainerContentEvent>()
- .add_event::<SetSelectedHotbarSlotEvent>()
+ app.add_message::<SetSelectedHotbarSlotEvent>()
.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<MenuOpenedEvent>, mut query: Query<&mut Inventory>) {
+fn handle_menu_opened_trigger(event: On<MenuOpenedEvent>, 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<MenuOpenedEvent>, 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<CloseContainerEvent>,
- mut client_side_events: EventWriter<ClientsideCloseContainerEvent>,
+ close_container: On<CloseContainerEvent>,
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<ClientsideCloseContainerEvent>,
+ event: On<ClientsideCloseContainerEvent>,
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<ClientsideCloseContainerEvent>,
-) {
- 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<ContainerClickEvent>,
mut query: Query<(
Entity,
&mut Inventory,
Option<&PlayerAbilities>,
&InstanceName,
)>,
- mut events: EventReader<ContainerClickEvent>,
- mut commands: Commands,
instance_container: Res<InstanceContainer>,
) {
- 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<u16, HashedStack> = 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<u16, HashedStack> = 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<ItemStack>,
pub container_id: i32,
}
pub fn handle_set_container_content_trigger(
- event: Trigger<SetContainerContentEvent>,
+ set_container_content: On<SetContainerContentEvent>,
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<SetSelectedHotbarSlotEvent>,
+ mut events: MessageReader<SetSelectedHotbarSlotEvent>,
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::<StartJoinServerEvent>()
- .add_event::<ConnectionFailedEvent>()
+ app.add_message::<StartJoinServerEvent>()
+ .add_message::<ConnectionFailedEvent>()
.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<StartJoinServerEvent>,
+ mut events: MessageReader<StartJoinServerEvent>,
mut entity_uuid_index: ResMut<EntityUuidIndex>,
connection_query: Query<&RawConnection>,
) {
@@ -184,7 +184,7 @@ pub struct CreateConnectionTask(pub Task<Result<LoginConn, ConnectionError>>);
pub fn poll_create_connection_task(
mut commands: Commands,
mut query: Query<(Entity, &mut CreateConnectionTask, &Account)>,
- mut connection_failed_events: EventWriter<ConnectionFailedEvent>,
+ mut connection_failed_events: MessageWriter<ConnectionFailedEvent>,
) {
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<ReceiveHelloEvent>, mut commands: Commands) {
+fn handle_receive_hello_event(receive_hello: On<ReceiveHelloEvent>, 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<ReceiveCustomQueryEvent>,
+ mut events: MessageReader<ReceiveCustomQueryEvent>,
) {
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::<StartMiningBlockEvent>()
- .add_event::<FinishMiningBlockEvent>()
- .add_event::<StopMiningBlockEvent>()
- .add_event::<MineBlockProgressEvent>()
- .add_event::<AttackBlockEvent>()
+ app.add_message::<StartMiningBlockEvent>()
+ .add_message::<StopMiningBlockEvent>()
+ .add_message::<MineBlockProgressEvent>()
+ .add_message::<AttackBlockEvent>()
.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<LeftClickMine>,
>,
- mut start_mining_block_event: EventWriter<StartMiningBlockEvent>,
- mut stop_mining_block_event: EventWriter<StopMiningBlockEvent>,
+ mut start_mining_block_event: MessageWriter<StartMiningBlockEvent>,
+ mut stop_mining_block_event: MessageWriter<StopMiningBlockEvent>,
) {
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<StartMiningBlockEvent>,
+ mut events: MessageReader<StartMiningBlockEvent>,
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<AttackBlockEvent>,
- mut mine_block_progress_events: EventWriter<MineBlockProgressEvent>,
+ mut attack_block_events: MessageWriter<AttackBlockEvent>,
+ mut mine_block_progress_events: MessageWriter<MineBlockProgressEvent>,
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<BlockPos>);
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<FinishMiningBlockEvent>,
+ finish_mining_block: On<FinishMiningBlockEvent>,
mut query: Query<(
&InstanceName,
&LocalGameMode,
@@ -459,7 +454,7 @@ pub fn handle_finish_mining_block_observer(
)>,
instances: Res<InstanceContainer>,
) {
- 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<StopMiningBlockEvent>,
+ mut events: MessageReader<StopMiningBlockEvent>,
mut commands: Commands,
- mut mine_block_progress_events: EventWriter<MineBlockProgressEvent>,
+ mut mine_block_progress_events: MessageWriter<MineBlockProgressEvent>,
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<MineBlockProgressEvent>,
+ mut mine_block_progress_events: MessageWriter<MineBlockProgressEvent>,
instances: Res<InstanceContainer>,
) {
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::<StartWalkEvent>()
- .add_event::<StartSprintEvent>()
- .add_event::<KnockbackEvent>()
+ app.add_message::<StartWalkEvent>()
+ .add_message::<StartSprintEvent>()
+ .add_message::<KnockbackEvent>()
.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<StartWalkEvent>,
+ mut events: MessageReader<StartWalkEvent>,
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<StartSprintEvent>,
+ mut events: MessageReader<StartSprintEvent>,
) {
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<KnockbackEvent>) {
+pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: MessageReader<KnockbackEvent>) {
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<SendConfigPacketEvent>,
+ send_config_packet: On<SendConfigPacketEvent>,
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<SendConfigPacketEvent>,
-) {
- 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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<Commands>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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<ReceiveGamePacketEvent>) {
+/// fn handle_packets(mut events: MessageReader<ReceiveGamePacketEvent>) {
/// 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<SendPacketEvent>,
+ trigger: On<SendPacketEvent>,
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<SendPacketEvent>) {
- 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<ClientboundPlayerCombatKill>,
@@ -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<PingEvent>` will not work.
-///
-/// To use it, add your "system" with `add_observer` instead of `add_systems`
-/// and use `Trigger<PingEvent>` 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<LocalEntity>,
>,
- EventWriter<InstanceLoadedEvent>,
+ MessageWriter<InstanceLoadedEvent>,
ResMut<InstanceContainer>,
ResMut<EntityUuidIndex>,
Query<&mut LoadedBy, Without<LocalEntity>>,
@@ -336,7 +336,7 @@ impl GamePacketHandler<'_> {
// ends
debug!("Got chunk batch start");
- as_system::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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<AddPlayerEvent>,
- EventWriter<UpdatePlayerEvent>,
+ MessageWriter<AddPlayerEvent>,
+ MessageWriter<UpdatePlayerEvent>,
ResMut<TabList>,
)>(
self.ecs,
@@ -500,7 +500,7 @@ impl GamePacketHandler<'_> {
as_system::<(
Query<&mut TabList>,
- EventWriter<RemovePlayerEvent>,
+ MessageWriter<RemovePlayerEvent>,
ResMut<TabList>,
)>(
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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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<KeepAliveEvent>, Commands)>(
+ as_system::<(MessageWriter<KeepAliveEvent>, 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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<_>>(self.ecs, |mut knockback_events| {
+ as_system::<MessageWriter<_>>(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::<Commands>(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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(self.ecs, |mut events| {
events.write(ResourcePackEvent {
entity: self.player,
id: p.id,
@@ -1343,7 +1346,7 @@ impl GamePacketHandler<'_> {
),
With<LocalEntity>,
>,
- EventWriter<_>,
+ MessageWriter<_>,
ResMut<InstanceContainer>,
Query<&mut LoadedBy, Without<LocalEntity>>,
)>(
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<ClientboundLoginPacket>,
}
-#[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<SendLoginPacketEvent>,
+ trigger: On<SendLoginPacketEvent>,
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<SendLoginPacketEvent>,
-) {
- 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::<EventWriter<_>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<_>>(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::<EventWriter<ReceiveCustomQueryEvent>>(self.ecs, |mut events| {
+ as_system::<MessageWriter<ReceiveCustomQueryEvent>>(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<Health>>,
- mut death_events: EventWriter<DeathEvent>,
+ mut death_events: MessageWriter<DeathEvent>,
) {
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::<game::ReceiveGamePacketEvent>()
- .add_event::<config::ReceiveConfigPacketEvent>()
- .add_event::<login::ReceiveLoginPacketEvent>()
+ .add_systems(Update, death_event_on_0_health.before(death_listener))
+ .add_message::<game::ReceiveGamePacketEvent>()
+ .add_message::<config::ReceiveConfigPacketEvent>()
+ .add_message::<login::ReceiveLoginPacketEvent>()
//
- .add_event::<game::SendPacketEvent>()
- .add_event::<config::SendConfigPacketEvent>()
- .add_event::<login::SendLoginPacketEvent>()
- //
- .add_event::<game::AddPlayerEvent>()
- .add_event::<game::RemovePlayerEvent>()
- .add_event::<game::UpdatePlayerEvent>()
- .add_event::<ChatReceivedEvent>()
- .add_event::<game::DeathEvent>()
- .add_event::<game::KeepAliveEvent>()
- .add_event::<game::ResourcePackEvent>()
- .add_event::<game::InstanceLoadedEvent>()
- .add_event::<login::ReceiveCustomQueryEvent>();
+ .add_message::<game::AddPlayerEvent>()
+ .add_message::<game::RemovePlayerEvent>()
+ .add_message::<game::UpdatePlayerEvent>()
+ .add_message::<ChatReceivedEvent>()
+ .add_message::<game::DeathEvent>()
+ .add_message::<game::KeepAliveEvent>()
+ .add_message::<game::ResourcePackEvent>()
+ .add_message::<game::InstanceLoadedEvent>()
+ .add_message::<login::ReceiveCustomQueryEvent>();
}
}
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<PingEvent>, mut commands: Commands) {
+pub fn reply_to_game_ping(ping: On<PingEvent>, 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<ConfigPingEvent>, mut commands: Commands) {
+pub fn reply_to_config_ping(ping: On<ConfigPingEvent>, 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::<PerformRespawnEvent>()
+ app.add_message::<PerformRespawnEvent>()
.add_systems(Update, perform_respawn);
}
}
-pub fn perform_respawn(mut events: EventReader<PerformRespawnEvent>, mut commands: Commands) {
+pub fn perform_respawn(mut events: MessageReader<PerformRespawnEvent>, 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<Trigger<'a>: 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<SendPacketEvent>| {
- if trigger.sent_by == simulation_entity {
+ .add_observer(move |send_game_packet: On<SendPacketEvent>| {
+ 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::<InstanceName>());
simulation.tick();
- // we shouldn't be using the `SendPacketEvent` event directly, we should be
- // using the trigger instead
- simulation.with_resource_mut::<Events<SendPacketEvent>>(|send_packet_events| {
- assert_eq!(send_packet_events.len(), 0);
- });
-
simulation.receive_packet(ClientboundStartConfiguration);
simulation.tick();
assert!(simulation.has_component::<InConfigState>());
-
- // check again just in case
- simulation.with_resource_mut::<Events<SendPacketEvent>>(|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<SendConfigPacketEvent>| {
- if trigger.sent_by == simulation.entity
- && let ServerboundConfigPacket::Pong(packet) = &trigger.packet
+ .add_observer(move |send_config_packet: On<SendConfigPacketEvent>| {
+ 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<SendPacketEvent>| {
- if trigger.sent_by == simulation.entity
- && let ServerboundGamePacket::Pong(packet) = &trigger.packet
+ .add_observer(move |send_game_packet: On<SendPacketEvent>| {
+ 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<Entity, (With<LocalEntity>, With<Player>)>,
entities: EntityFinder,
entity_positions: Query<(&Position, Option<&EntityDimensions>)>,
- mut look_at_event: EventWriter<LookAtEvent>,
+ mut look_at_event: MessageWriter<LookAtEvent>,
) {
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<Mutex<CommandSource>>) {
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::<EntityRef>();
+ 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::<Vec<_>>();
writeln!(
report,
@@ -274,12 +276,12 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
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::<InstanceContainer>();
@@ -311,12 +313,12 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
}
}
}
- "bevy_ecs::event::collections::Events<azalea_client::packet::game::ReceivePacketEvent>" => {
- let events = ecs.resource::<Events<game::ReceiveGamePacketEvent>>();
+ "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
+ let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
writeln!(report, "- Event count: {}", events.len()).unwrap();
}
- "bevy_ecs::event::collections::Events<azalea_client::chunks::ReceiveChunkEvent>" => {
- let events = ecs.resource::<Events<ReceiveChunkEvent>>();
+ "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
+ let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
writeln!(report, "- Event count: {}", events.len()).unwrap();
}
@@ -340,7 +342,7 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
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<ResourcePackEvent>,
+ mut events: MessageReader<ResourcePackEvent>,
mut commands: Commands,
query_in_config_state: Query<Option<&InConfigState>>,
) {
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<DeathEvent>,
- mut perform_respawn_events: EventWriter<PerformRespawnEvent>,
+ mut events: MessageReader<DeathEvent>,
+ mut perform_respawn_events: MessageWriter<PerformRespawnEvent>,
) {
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::<LookAtEvent>()
- .add_event::<JumpEvent>()
+ app.add_message::<LookAtEvent>()
+ .add_message::<JumpEvent>()
.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<JumpEvent>,
+ mut events: MessageReader<JumpEvent>,
) {
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<LookAtEvent>,
+ mut events: MessageReader<LookAtEvent>,
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::<Inventory>(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| 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<ClickOperation>) {
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<ReceiveGamePacketEvent>,
+ mut events: MessageReader<ReceiveGamePacketEvent>,
) {
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<Entity, (With<LocalEntity>, With<Player>)>,
/// entity_finder: EntityFinder<With<AbstractMonster>>,
-/// mut chat_events: EventWriter<SendChatEvent>,
+/// mut chat_events: MessageWriter<SendChatEvent>,
/// ) {
/// 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<PathfinderDebugParticles>>,
// chat_events is Option because the tests don't have SendChatEvent
- // and we have to use ResMut<Events> because bevy doesn't support Option<EventWriter>
- chat_events: Option<ResMut<Events<SendChatEvent>>>,
+ // and we have to use ResMut<Messages> because bevy doesn't support Option<MessageWriter>
+ chat_events: Option<ResMut<Messages<SendChatEvent>>>,
mut tick_count: Local<usize>,
) {
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::<GotoEvent>()
- .add_event::<PathFoundEvent>()
- .add_event::<StopPathfindingEvent>()
+ app.add_message::<GotoEvent>()
+ .add_message::<PathFoundEvent>()
+ .add_message::<StopPathfindingEvent>()
.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::<Pathfinder, _>(|p| p.goal.is_none() && !p.is_calculating)
- .unwrap_or(true)
+ self.query_self::<Option<&Pathfinder>, _>(|p| {
+ p.map(|p| p.goal.is_none() && !p.is_calculating)
+ .unwrap_or(true)
+ })
}
}
@@ -281,7 +282,7 @@ pub struct ComputePath(Task<Option<PathFoundEvent>>);
#[allow(clippy::type_complexity)]
pub fn goto_listener(
mut commands: Commands,
- mut events: EventReader<GotoEvent>,
+ mut events: MessageReader<GotoEvent>,
mut query: Query<(
&mut Pathfinder,
Option<&ExecutingPath>,
@@ -499,7 +500,7 @@ pub fn calculate_path(ctx: CalculatePathCtx) -> Option<PathFoundEvent> {
pub fn handle_tasks(
mut commands: Commands,
mut transform_tasks: Query<(Entity, &mut ComputePath)>,
- mut path_found_events: EventWriter<PathFoundEvent>,
+ mut path_found_events: MessageWriter<PathFoundEvent>,
) {
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<PathFoundEvent>,
+ mut events: MessageReader<PathFoundEvent>,
mut query: Query<(
&mut Pathfinder,
Option<&mut ExecutingPath>,
@@ -709,7 +710,7 @@ pub fn check_node_reached(
&Position,
&Physics,
)>,
- mut walk_events: EventWriter<StartWalkEvent>,
+ mut walk_events: MessageWriter<StartWalkEvent>,
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<StartWalkEvent>,
- mut goto_events: EventWriter<GotoEvent>,
+ mut walk_events: MessageWriter<StartWalkEvent>,
+ mut goto_events: MessageWriter<GotoEvent>,
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<LookAtEvent>,
- mut sprint_events: EventWriter<StartSprintEvent>,
- mut walk_events: EventWriter<StartWalkEvent>,
- mut jump_events: EventWriter<JumpEvent>,
- mut start_mining_events: EventWriter<StartMiningBlockEvent>,
- mut set_selected_hotbar_slot_events: EventWriter<SetSelectedHotbarSlotEvent>,
+ mut look_at_events: MessageWriter<LookAtEvent>,
+ mut sprint_events: MessageWriter<StartSprintEvent>,
+ mut walk_events: MessageWriter<StartWalkEvent>,
+ mut jump_events: MessageWriter<JumpEvent>,
+ mut start_mining_events: MessageWriter<StartMiningBlockEvent>,
+ mut set_selected_hotbar_slot_events: MessageWriter<SetSelectedHotbarSlotEvent>,
) {
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<ExecutingPath>>,
- mut goto_events: EventWriter<GotoEvent>,
+ mut goto_events: MessageWriter<GotoEvent>,
) {
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<StopPathfindingEvent>,
+ mut events: MessageReader<StopPathfindingEvent>,
mut query: Query<(&mut Pathfinder, &mut ExecutingPath)>,
- mut walk_events: EventWriter<StartWalkEvent>,
+ mut walk_events: MessageWriter<StartWalkEvent>,
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<InstanceName>>,
- mut stop_pathfinding_events: EventWriter<StopPathfindingEvent>,
+ mut stop_pathfinding_events: MessageWriter<StopPathfindingEvent>,
) {
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<RwLock<Instance>>,
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<RwLock<Instance
.iter()
.cloned()
.collect(),
- })
- .add_event::<SendPacketEvent>();
+ });
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::<NewChatMessageEvent>()
+ app.add_message::<NewChatMessageEvent>()
.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<ChatReceivedEvent>,
+ mut events: MessageReader<ChatReceivedEvent>,
mut global_chat_state: ResMut<GlobalChatState>,
- mut new_chat_messages_events: EventWriter<NewChatMessageEvent>,
+ mut new_chat_messages_events: MessageWriter<NewChatMessageEvent>,
) {
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<GlobalChatState>,
- mut events: EventReader<NewChatMessageEvent>,
+ mut events: MessageReader<NewChatMessageEvent>,
swarm: Option<Res<Swarm>>,
) {
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::<Events<ChatReceivedEvent>>()
- .init_resource::<Events<NewChatMessageEvent>>()
+ // 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::<Messages<ChatReceivedEvent>>()
+ .init_resource::<Messages<NewChatMessageEvent>>()
.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<ChatPacket> {
- let mut system_state: SystemState<ResMut<Events<NewChatMessageEvent>>> =
+ fn drain_messages(ecs: &mut World) -> Vec<ChatPacket> {
+ let mut system_state: SystemState<ResMut<Messages<NewChatMessageEvent>>> =
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::<Vec<_>>()
+ messages.drain().map(|e| e.0.clone()).collect::<Vec<_>>()
}
#[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::<ClientChatState>(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::<ClientChatState>(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::<SwarmReadyEvent>()
+ app.add_message::<SwarmReadyEvent>()
.add_systems(Update, check_ready)
.init_resource::<IsSwarmReady>();
}
}
/// 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<Option<&MinecraftEntityId>, With<InstanceHolder>>,
mut is_swarm_ready: ResMut<IsSwarmReady>,
- mut ready_events: EventWriter<SwarmReadyEvent>,
+ mut ready_events: MessageWriter<SwarmReadyEvent>,
) {
// if we already know the swarm is ready, do nothing
if **is_swarm_ready {