diff --git a/Cargo.lock b/Cargo.lock index 5b88f1c3..d342c77b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android_log-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" + [[package]] name = "anyhow" version = "1.0.68" @@ -177,7 +183,6 @@ dependencies = [ "azalea-world", "bevy_tasks", "derive_more", - "env_logger 0.10.0", "futures", "futures-lite", "log", @@ -197,7 +202,7 @@ dependencies = [ "azalea-buf", "azalea-crypto", "chrono", - "env_logger 0.9.3", + "env_logger", "log", "num-bigint", "reqwest", @@ -284,10 +289,10 @@ dependencies = [ "azalea-protocol", "azalea-registry", "azalea-world", + "bevy_log", "bevy_tasks", "bevy_time", "derive_more", - "env_logger 0.9.3", "futures", "log", "nohash-hasher", @@ -548,6 +553,22 @@ dependencies = [ "syn", ] +[[package]] +name = "bevy_log" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c480bac54cf4ae76edc3ae9ae3fa7c5e1b385e7f2111ef5ec3fd00cf3a7998b" +dependencies = [ + "android_log-sys", + "bevy_app", + "bevy_ecs", + "bevy_utils", + "console_error_panic_hook", + "tracing-log", + "tracing-subscriber", + "tracing-wasm", +] + [[package]] name = "bevy_macro_utils" version = "0.9.1" @@ -799,6 +820,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1009,19 +1040,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "erased-serde" version = "0.3.24" @@ -1031,27 +1049,6 @@ dependencies = [ "serde", ] -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "event-listener" version = "2.5.3" @@ -1438,34 +1435,12 @@ dependencies = [ "web-sys", ] -[[package]] -name = "io-lifetimes" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" -dependencies = [ - "libc", - "windows-sys", -] - [[package]] name = "ipnet" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" -[[package]] -name = "is-terminal" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" -dependencies = [ - "hermit-abi 0.2.6", - "io-lifetimes", - "rustix", - "windows-sys", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1514,12 +1489,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linux-raw-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - [[package]] name = "lock_api" version = "0.4.9" @@ -1548,6 +1517,15 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.10" @@ -1944,6 +1922,9 @@ name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] [[package]] name = "regex-syntax" @@ -2031,20 +2012,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys", -] - [[package]] name = "rustls" version = "0.20.8" @@ -2489,14 +2456,29 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ + "matchers", "nu-ansi-term", + "once_cell", + "regex", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + [[package]] name = "trust-dns-proto" version = "0.22.0" diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml index 9fae2fbe..6bb31069 100644 --- a/azalea-client/Cargo.toml +++ b/azalea-client/Cargo.toml @@ -11,29 +11,27 @@ version = "0.6.0" [dependencies] anyhow = "1.0.59" async-trait = "0.1.58" -azalea-auth = {path = "../azalea-auth", version = "0.6.0"} -azalea-block = {path = "../azalea-block", version = "0.6.0"} -azalea-chat = {path = "../azalea-chat", version = "0.6.0"} -azalea-core = {path = "../azalea-core", version = "0.6.0"} -azalea-crypto = {path = "../azalea-crypto", version = "0.6.0"} -azalea-ecs = {path = "../azalea-ecs", version = "0.6.0"} -azalea-physics = {path = "../azalea-physics", version = "0.6.0"} -azalea-protocol = {path = "../azalea-protocol", version = "0.6.0"} -azalea-registry = {path = "../azalea-registry", version = "0.6.0"} -azalea-world = {path = "../azalea-world", version = "0.6.0"} +azalea-auth = { path = "../azalea-auth", version = "0.6.0" } +azalea-block = { path = "../azalea-block", version = "0.6.0" } +azalea-chat = { path = "../azalea-chat", version = "0.6.0" } +azalea-core = { path = "../azalea-core", version = "0.6.0" } +azalea-crypto = { path = "../azalea-crypto", version = "0.6.0" } +azalea-ecs = { path = "../azalea-ecs", version = "0.6.0" } +azalea-physics = { path = "../azalea-physics", version = "0.6.0" } +azalea-protocol = { path = "../azalea-protocol", version = "0.6.0" } +azalea-registry = { path = "../azalea-registry", version = "0.6.0" } +azalea-world = { path = "../azalea-world", version = "0.6.0" } +bevy_log = "0.9.1" bevy_tasks = "0.9.1" bevy_time = "0.9.1" -derive_more = {version = "0.99.17", features = ["deref", "deref_mut"]} +derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] } futures = "0.3.25" log = "0.4.17" nohash-hasher = "0.2.0" once_cell = "1.16.0" -parking_lot = {version = "^0.12.1", features = ["deadlock_detection"]} +parking_lot = { version = "^0.12.1", features = ["deadlock_detection"] } regex = "1.7.0" thiserror = "^1.0.34" -tokio = {version = "^1.24.2", features = ["sync"]} +tokio = { version = "^1.24.2", features = ["sync"] } typemap_rev = "0.3.0" uuid = "^1.1.2" - -[dev-dependencies] -env_logger = "0.9.1" diff --git a/azalea-client/examples/echo.rs b/azalea-client/examples/echo.rs deleted file mode 100644 index f37cd904..00000000 --- a/azalea-client/examples/echo.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! A simple bot that repeats chat messages sent by other players. - -use azalea_client::{Account, Client, Event}; - -#[tokio::main] -async fn main() { - env_logger::init(); - // deadlock detection, you can safely delete this block if you're not trying to - // debug deadlocks in azalea - { - use parking_lot::deadlock; - use std::thread; - use std::time::Duration; - thread::spawn(move || loop { - thread::sleep(Duration::from_secs(10)); - let deadlocks = deadlock::check_deadlock(); - if deadlocks.is_empty() { - continue; - } - println!("{} deadlocks detected", deadlocks.len()); - for (i, threads) in deadlocks.iter().enumerate() { - println!("Deadlock #{i}"); - for t in threads { - println!("Thread Id {:#?}", t.thread_id()); - println!("{:#?}", t.backtrace()); - } - } - }); - } - - let account = Account::offline("bot"); - // or let account = Account::microsoft("email").await; - - let (client, mut rx) = Client::join(&account, "localhost").await.unwrap(); - - while let Some(event) = rx.recv().await { - match &event { - Event::Chat(m) => { - if let (Some(sender), content) = m.split_sender_and_content() { - if sender == client.profile.name { - continue; // ignore our own messages - } - client.chat(&content); - }; - } - _ => {} - } - } -} diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index ac119f24..202cf47c 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -19,7 +19,10 @@ use std::{ }; use uuid::Uuid; -use crate::{client::Client, local_player::SendPacketEvent}; +use crate::{ + client::Client, + local_player::{handle_send_packet_event, SendPacketEvent}, +}; /// A chat packet, either a system message or a chat message. #[derive(Debug, Clone, PartialEq)] @@ -155,15 +158,12 @@ impl Plugin for ChatPlugin { app.add_event::() .add_event::() .add_event::() - .add_system( - handle_send_chat_event - .label("handle_send_chat_event") - .after("packet"), - ) + .add_system(handle_send_chat_event.label("handle_send_chat_event")) .add_system( handle_send_chat_kind_event .label("handle_send_chat_kind_event") - .after("handle_send_chat_event"), + .after(handle_send_chat_event) + .after(handle_send_packet_event), ); } } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 69a50c33..661858db 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -20,7 +20,7 @@ use azalea_ecs::{ bundle::Bundle, component::Component, entity::Entity, - schedule::{IntoSystemDescriptor, Schedule, Stage, SystemSet}, + schedule::{IntoSystemDescriptor, ReportExecutionOrderAmbiguities, Schedule, Stage, SystemSet}, AppTickExt, }; use azalea_ecs::{ecs::Ecs, TickPlugin}; @@ -49,6 +49,7 @@ use azalea_world::{ entity::{EntityPlugin, Local, WorldName}, PartialWorld, World, WorldContainer, }; +use bevy_log::LogPlugin; use log::{debug, error}; use parking_lot::{Mutex, RwLock}; use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc}; @@ -497,36 +498,31 @@ impl Plugin for AzaleaPlugin { app.add_tick_system_set( SystemSet::new() - .with_system(send_position) - .with_system(update_in_loaded_chunk) + .with_system(send_position.after("ai_step")) + .with_system(update_in_loaded_chunk.before(send_position).after("travel")) .with_system( local_player_ai_step - .before("ai_step") - .after("sprint_listener"), + .before(azalea_physics::ai_step) + .label("ai_step"), ), ); // fire the Death event when the player dies. - app.add_system(death_event.after("tick").after("packet")); + app.add_system(death_event); // walk and sprint event listeners - app.add_system(walk_listener.label("walk_listener").before("travel")) + app.add_system(walk_listener.label("walk_listener")) .add_system( sprint_listener .label("sprint_listener") - .before("travel") .before("walk_listener"), ); // add GameProfileComponent when we get an AddPlayerEvent - app.add_system( - retroactively_add_game_profile_component - .after("tick") - .after("packet"), - ); + app.add_system(retroactively_add_game_profile_component.after("update_indexes")); app.add_event::() - .add_system(handle_send_packet_event.after("tick").after("packet")); + .add_system(handle_send_packet_event); app.init_resource::(); } @@ -547,6 +543,9 @@ pub fn init_ecs_app() -> App { // you might be able to just drop the lock or put it in its own scope to fix let mut app = App::new(); + + app.insert_resource(ReportExecutionOrderAmbiguities); + app.add_plugins(DefaultPlugins); app } @@ -609,9 +608,10 @@ pub struct DefaultPlugins; impl PluginGroup for DefaultPlugins { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::() + .add(LogPlugin::default()) .add(TickPlugin::default()) - .add(AzaleaPlugin) .add(PacketHandlerPlugin) + .add(AzaleaPlugin) .add(EntityPlugin) .add(PhysicsPlugin) .add(EventPlugin) diff --git a/azalea-client/src/disconnect.rs b/azalea-client/src/disconnect.rs index 83870e69..9fd57e57 100644 --- a/azalea-client/src/disconnect.rs +++ b/azalea-client/src/disconnect.rs @@ -12,7 +12,7 @@ use azalea_ecs::{ }; use derive_more::Deref; -use crate::{client::JoinedClientBundle, LocalPlayer}; +use crate::{client::JoinedClientBundle, movement::send_position, LocalPlayer}; pub struct DisconnectPlugin; impl Plugin for DisconnectPlugin { @@ -20,7 +20,9 @@ impl Plugin for DisconnectPlugin { app.add_event::() .add_system_to_stage(CoreStage::PostUpdate, handle_disconnect) .add_tick_system( - update_read_packets_task_running_component.before(disconnect_on_read_packets_ended), + update_read_packets_task_running_component + .before(disconnect_on_read_packets_ended) + .before(send_position), ) .add_tick_system(disconnect_on_read_packets_ended); } diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs index d5cce3a8..a4d638a4 100644 --- a/azalea-client/src/packet_handling.rs +++ b/azalea-client/src/packet_handling.rs @@ -2,13 +2,12 @@ use std::{collections::HashSet, io::Cursor, sync::Arc}; use azalea_core::{ChunkPos, ResourceLocation, Vec3}; use azalea_ecs::{ - app::{App, Plugin}, + app::{App, CoreStage, Plugin}, component::Component, ecs::Ecs, entity::Entity, event::EventWriter, query::Changed, - schedule::{IntoSystemDescriptor, SystemSet}, system::{Commands, Query, ResMut, SystemState}, }; use azalea_protocol::{ @@ -47,15 +46,13 @@ pub struct PacketHandlerPlugin; impl Plugin for PacketHandlerPlugin { fn build(&self, app: &mut App) { - app.add_system_set( - SystemSet::new().with_system(handle_packets.label("packet").before("tick")), - ) - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::(); + app.add_system_to_stage(CoreStage::PreUpdate, handle_packets) + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::(); } } @@ -110,7 +107,7 @@ pub struct PacketReceiver { pub run_schedule_sender: mpsc::UnboundedSender<()>, } -fn handle_packets(ecs: &mut Ecs) { +pub fn handle_packets(ecs: &mut Ecs) { let mut events_owned = Vec::new(); { diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index 8bccedc8..3680e2d0 100755 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -36,9 +36,9 @@ pub fn retroactively_add_game_profile_component( ) { for event in events.iter() { if let Some(entity) = entity_infos.get_entity_by_uuid(&event.info.uuid) { - if let Some(mut entity_commands) = commands.get_entity(entity) { - entity_commands.insert(GameProfileComponent(event.info.profile.clone())); - } + commands + .entity(entity) + .insert(GameProfileComponent(event.info.profile.clone())); } } } diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index 23b05fef..0a8f8a8b 100644 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -10,7 +10,7 @@ use azalea_ecs::{ entity::Entity, event::{EventReader, EventWriter}, query::With, - schedule::{IntoSystemDescriptor, SystemSet}, + schedule::IntoSystemDescriptor, system::{Query, Res}, AppTickExt, }; @@ -30,14 +30,11 @@ impl Plugin for PhysicsPlugin { .add_system( force_jump_listener .label("force_jump_listener") - .after("ai_step"), - ) - .add_system( - travel - .label("travel") - .after("ai_step") - .after("force_jump_listener"), + .after("walk_listener") + .after("sprint_listener") + .before(azalea_world::entity::update_bounding_box), ) + .add_tick_system(travel.label("travel").after(ai_step)) .add_tick_system(ai_step.label("ai_step")); } } diff --git a/azalea-protocol/src/lib.rs b/azalea-protocol/src/lib.rs index d9860a8b..8c357905 100644 --- a/azalea-protocol/src/lib.rs +++ b/azalea-protocol/src/lib.rs @@ -79,10 +79,7 @@ impl Display for ServerAddress { #[cfg(test)] mod tests { - use std::{ - io::Cursor, - time::{SystemTime, UNIX_EPOCH}, - }; + use std::io::Cursor; use crate::{ packets::{ diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs index 1018c085..5436fb1d 100755 --- a/azalea-protocol/src/read.rs +++ b/azalea-protocol/src/read.rs @@ -264,6 +264,7 @@ mod tests { use crate::packets::game::ClientboundGamePacket; use std::io::Cursor; + #[test] fn test_read_packet() { let mut buf: Cursor<&[u8]> = Cursor::new(&[ 56, 64, 85, 58, 141, 138, 71, 146, 193, 64, 88, 0, 0, 0, 0, 0, 0, 64, 60, 224, 105, 34, diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml index 794ed48e..4d53cabd 100644 --- a/azalea-world/Cargo.toml +++ b/azalea-world/Cargo.toml @@ -9,14 +9,16 @@ version = "0.6.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -azalea-block = {path = "../azalea-block", default-features = false, version = "^0.6.0"} -azalea-buf = {path = "../azalea-buf", version = "^0.6.0"} -azalea-chat = {path = "../azalea-chat", version = "^0.6.0"} -azalea-core = {path = "../azalea-core", version = "^0.6.0", features = ["bevy_ecs"]} -azalea-ecs = {version = "0.6.0", path = "../azalea-ecs"} -azalea-nbt = {path = "../azalea-nbt", version = "^0.6.0"} -azalea-registry = {path = "../azalea-registry", version = "^0.6.0"} -derive_more = {version = "0.99.17", features = ["deref", "deref_mut"]} +azalea-block = { path = "../azalea-block", default-features = false, version = "^0.6.0" } +azalea-buf = { path = "../azalea-buf", version = "^0.6.0" } +azalea-chat = { path = "../azalea-chat", version = "^0.6.0" } +azalea-core = { path = "../azalea-core", version = "^0.6.0", features = [ + "bevy_ecs", +] } +azalea-ecs = { version = "0.6.0", path = "../azalea-ecs" } +azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" } +azalea-registry = { path = "../azalea-registry", version = "^0.6.0" } +derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] } enum-as-inner = "0.5.1" log = "0.4.17" nohash-hasher = "0.2.0" diff --git a/azalea-world/src/entity/info.rs b/azalea-world/src/entity/info.rs index 48636c5b..8615ef81 100644 --- a/azalea-world/src/entity/info.rs +++ b/azalea-world/src/entity/info.rs @@ -36,52 +36,45 @@ use super::Local; pub struct EntityPlugin; impl Plugin for EntityPlugin { fn build(&self, app: &mut App) { - app.add_system_set( - SystemSet::new() - .after("tick") - .after("packet") - .with_system(update_entity_chunk_positions) - .with_system(remove_despawned_entities_from_indexes) - .with_system(update_bounding_box) - .with_system(add_dead) - .with_system( - add_updates_received - .after("deduplicate_entities") - .after("deduplicate_local_entities") - .label("add_updates_received"), - ) - .with_system( - update_uuid_index - .label("update_uuid_index") - .after("deduplicate_local_entities") - .after("deduplicate_entities"), - ) - .with_system(debug_detect_updates_received_on_local_entities) - .with_system( - update_entity_by_id_index - .label("update_entity_by_id_index") - .after("deduplicate_entities"), - ) - .with_system(debug_new_entity), + // entities get added pre-update + // added to indexes during update (done by this plugin) + // modified during update + // despawned post-update (done by this plugin) + app.add_system_set_to_stage( + CoreStage::PreUpdate, + SystemSet::new().with_system(remove_despawned_entities_from_indexes), ) .add_system_set_to_stage( CoreStage::PostUpdate, SystemSet::new() .with_system(deduplicate_entities.label("deduplicate_entities")) - .with_system( - deduplicate_local_entities - .label("deduplicate_local_entities") - .before("update_uuid_index") - .before("update_entity_by_id_index"), - ), + .with_system(deduplicate_local_entities.label("deduplicate_entities")), + ) + .add_system_set( + SystemSet::new() + .with_system(update_entity_chunk_positions) + .with_system(update_uuid_index.label("update_indexes")) + .with_system(update_entity_by_id_index.label("update_indexes")), + ) + .add_system_set( + SystemSet::new() + .with_system(add_updates_received.label("add_updates_received")) + .with_system(debug_new_entity) + .with_system(debug_detect_updates_received_on_local_entities) + .with_system(add_dead) + .with_system(update_bounding_box), ) .init_resource::(); } } -fn debug_new_entity(query: Query>) { - for entity in query.iter() { - debug!("new entity: {:?}", entity); +fn debug_new_entity(query: Query<(Entity, Option<&Local>), Added>) { + for (entity, local) in query.iter() { + if local.is_some() { + debug!("new local entity: {:?}", entity); + } else { + debug!("new entity: {:?}", entity); + } } } diff --git a/azalea-world/src/world.rs b/azalea-world/src/world.rs index 53a1f377..8f1b2179 100644 --- a/azalea-world/src/world.rs +++ b/azalea-world/src/world.rs @@ -82,8 +82,8 @@ pub fn deduplicate_entities( } commands.entity(new_entity).despawn(); info!( - "Entity with id {id:?} / {new_entity:?} already existed in the world, merging it with {old_entity:?}" - ); + "Entity with id {id:?} / {new_entity:?} already existed in the world, merging it with {old_entity:?}" + ); break; } } else { @@ -127,15 +127,20 @@ pub fn deduplicate_local_entities( pub fn update_uuid_index( mut entity_infos: ResMut, - query: Query<(Entity, &EntityUuid), Changed>, + query: Query<(Entity, &EntityUuid, Option<&Local>), Changed>, ) { - for (entity, &uuid) in query.iter() { + for (entity, &uuid, local) in query.iter() { // only add it if it doesn't already exist in // entity_infos.entity_by_uuid - // if entity_infos.entity_by_uuid.contains_key(&uuid) { - // warn!("Entity with UUID {uuid:?} already existed in the world, not adding - // to index (ecs id: {entity:?})", uuid=*uuid); continue; - // } + if local.is_none() { + if let Some(old_entity) = entity_infos.entity_by_uuid.get(&uuid) { + debug!( + "Entity with UUID {uuid:?} already existed in the world, not adding to + index (old ecs id: {old_entity:?} / new ecs id: {entity:?})" + ); + continue; + } + } entity_infos.entity_by_uuid.insert(*uuid, entity); } } @@ -208,18 +213,24 @@ impl Default for PartialWorld { /// System to keep the entity_by_id index up-to-date. pub fn update_entity_by_id_index( - mut query: Query<(Entity, &MinecraftEntityId, &WorldName), Changed>, + mut query: Query< + (Entity, &MinecraftEntityId, &WorldName, Option<&Local>), + Changed, + >, world_container: Res, ) { - for (entity, id, world_name) in query.iter_mut() { + for (entity, id, world_name, local) in query.iter_mut() { let world_lock = world_container.get(world_name).unwrap(); let mut world = world_lock.write(); - // if let Some(old_entity) = world.entity_by_id.get(id) { - // warn!( - // "Entity with ID {id:?} already existed in the world, not adding to - // index (old ecs id: {old_entity:?} / new ecs id: {entity:?})" ); - // continue; - // } + if local.is_none() { + if let Some(old_entity) = world.entity_by_id.get(id) { + debug!( + "Entity with ID {id:?} already existed in the world, not adding to + index (old ecs id: {old_entity:?} / new ecs id: {entity:?})" + ); + continue; + } + } world.entity_by_id.insert(*id, entity); debug!("Added {entity:?} to {world_name:?} with {id:?}."); } diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml index 69129d4c..f64959ed 100644 --- a/azalea/Cargo.toml +++ b/azalea/Cargo.toml @@ -36,5 +36,3 @@ thiserror = "^1.0.37" tokio = "^1.24.2" uuid = "1.2.2" -[dev-dependencies] -env_logger = "^0.10.0" diff --git a/azalea/README.md b/azalea/README.md index a9c44461..21be566a 100755 --- a/azalea/README.md +++ b/azalea/README.md @@ -83,4 +83,25 @@ Also note that just because something is an entity in the ECS doesn't mean that See the [Bevy Cheatbook](https://bevy-cheatbook.github.io/programming/ecs-intro.html) to learn more about Bevy ECS (and the ECS paradigm in general). +# Debugging + +Azalea uses several relatively complex features of Rust, which may make debugging certain issues more tricky if you're not familiar with them. + +## Logging + +One of the most useful tools for debugging issues is logging. The default log level is `info`, but you can make it show more or less information by changing the log level. Enabling logging is done with `RUST_LOG=debug cargo run` on Linux/bash or `set RUST_LOG=debug && cargo run` on Windows. The log levels are `trace`, `debug`, `info`, `warn`, and `error`, in ascending priority. + +If it's a crash/panic and you believe it has to do with parsing a packet, you might want to set the level to `trace` since that'll make it show the first few hundred bytes of every packet received. This may produce a lot of logs, so pipe it into a file with `&> azalea.log` (on Linux). + +Note: If you get a `SetLoggerError`, it's because you have multiple loggers. Azalea comes with a logger by default, see [`bevy_log`] for more information. + +## Deadlocks + +If your code is simply hanging, it might be a deadlock. Copy the deadlock block in [`azalea/examples/testbot.rs`](https://github.com/mat-1/azalea/blob/main/azalea/examples/testbot.rs) to the beginning of your code and it'll print a long backtrace if a deadlock is detected. + +## Backtraces + +Backtraces are also useful, though they're sometimes hard to read and don't always contain the actual location of the error. Run your code with `RUST_BACKTRACE=1` to enable full backtraces. If it's very long, often searching for the keyword "azalea" will help you filter out unrelated things and find the actual source of the issue. + [`azalea_client`]: https://docs.rs/azalea-client +[`bevy_log`]: https://docs.rs/bevy_log diff --git a/azalea/examples/echo.rs b/azalea/examples/echo.rs index 46853bf4..292e12cd 100755 --- a/azalea/examples/echo.rs +++ b/azalea/examples/echo.rs @@ -4,8 +4,6 @@ use azalea::prelude::*; #[tokio::main] async fn main() { - env_logger::init(); - let account = Account::offline("bot"); // or let account = Account::microsoft("email").await; diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs index af236dc4..053e29b3 100644 --- a/azalea/examples/testbot.rs +++ b/azalea/examples/testbot.rs @@ -19,13 +19,10 @@ struct SwarmState {} #[tokio::main] async fn main() -> anyhow::Result<()> { - env_logger::init(); - { use parking_lot::deadlock; use std::thread; use std::time::Duration; - // Create a background thread which checks for deadlocks every 10s thread::spawn(move || loop { thread::sleep(Duration::from_secs(10)); @@ -48,7 +45,7 @@ async fn main() -> anyhow::Result<()> { let mut accounts = Vec::new(); let mut states = Vec::new(); - for i in 0..1 { + for i in 0..5 { accounts.push(Account::offline(&format!("bot{i}"))); states.push(State::default()); } diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs index 1f3822ac..ce5b9fdc 100644 --- a/azalea/src/bot.rs +++ b/azalea/src/bot.rs @@ -20,9 +20,13 @@ impl Plugin for BotPlugin { fn build(&self, app: &mut App) { app.add_event::() .add_event::() - .add_system(insert_bot.before("deduplicate_entities")) - .add_system(look_at_listener) - .add_system(jump_listener.label("jump_listener").before("ai_step")) + .add_system(insert_bot) + .add_system( + look_at_listener + .before("force_jump_listener") + .before(azalea_world::entity::update_bounding_box), + ) + .add_system(jump_listener.label("jump_listener")) .add_tick_system(stop_jumping.after("ai_step")); } } diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 1dfb7a9b..8289d9c4 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -36,10 +36,10 @@ impl Plugin for PathfinderPlugin { fn build(&self, app: &mut App) { app.add_event::() .add_event::() - .add_tick_system(tick_execute_path.before("walk_listener")) + .add_tick_system(tick_execute_path.before("ai_step")) .add_system(goto_listener) - .add_system(add_default_pathfinder.after("deduplicate_entities")) - .add_system(handle_tasks) + .add_system(add_default_pathfinder) + .add_system(handle_tasks.before(path_found_listener)) .add_system(path_found_listener); } }