diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs index 310bf66c..adfab9f4 100644 --- a/azalea/src/bot.rs +++ b/azalea/src/bot.rs @@ -1,3 +1,4 @@ +use azalea_client::Account; use azalea_core::Vec3; use azalea_world::entity::{set_rotation, Entity, Jumping, Physics, Position}; use bevy_app::App; diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs index eed72667..ce473ee0 100644 --- a/azalea/src/lib.rs +++ b/azalea/src/lib.rs @@ -92,7 +92,57 @@ pub use azalea_core::{BlockPos, Vec3}; pub use azalea_protocol as protocol; pub use azalea_registry::EntityKind; pub use azalea_world::{entity, World}; +use bevy_ecs::prelude::Component; +use futures::Future; +use protocol::ServerAddress; +use start::StartError; pub use start::{start, Options}; pub use swarm::*; pub type HandleFn = fn(Client, Event, S) -> Fut; + +pub struct ClientBuilder +where + S: Default + Send + Sync + Clone + 'static, + Fut: Future>, +{ + /// The function that's called every time a bot receives an [`Event`]. + handler: Option>, + state: S, +} +impl ClientBuilder +where + S: Default + Send + Sync + Clone + Component + 'static, + Fut: Future> + Send + 'static, +{ + pub fn new() -> Self { + Self { + handler: None, + state: S::default(), + } + } + pub fn set_handler(mut self, handler: HandleFn) -> Self { + self.handler = Some(handler); + self + } + pub async fn start( + self, + account: Account, + address: impl TryInto, + ) -> Result<(), StartError> { + let address = match address.try_into() { + Ok(address) => address, + Err(_) => return Err(StartError::InvalidAddress), + }; + + let (bot, mut rx) = Client::join(&account, address).await?; + + while let Some(event) = rx.recv().await { + if let Some(handler) = self.handler { + tokio::spawn((handler)(bot.clone(), event.clone(), self.state.clone())); + } + } + + Ok(()) + } +} diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs index 866e2a7f..26318114 100644 --- a/azalea/src/swarm/mod.rs +++ b/azalea/src/swarm/mod.rs @@ -49,10 +49,10 @@ pub struct Swarm { /// Create a new [`Swarm`]. pub struct SwarmBuilder where - Fut: Future>, - SwarmFut: Future>, S: Default + Send + Sync + Clone + 'static, SS: Default + Send + Sync + Clone + 'static, + Fut: Future>, + SwarmFut: Future>, { app: bevy_app::App, /// The accounts that are going to join the server. @@ -425,6 +425,7 @@ impl Swarm { self.bots.lock().insert(bot.entity, bot.clone()); + let cloned_bots = self.bots.clone(); let cloned_bots_tx = self.bots_tx.clone(); let cloned_bot = bot.clone(); let owned_account = account.clone(); @@ -439,7 +440,7 @@ impl Swarm { error!("Error sending event to swarm: {e}"); } } - self.bots.lock().remove(&bot.entity); + cloned_bots.lock().remove(&bot.entity); swarm_tx .send(SwarmEvent::Disconnect(owned_account)) .unwrap(); diff --git a/bot/src/main.rs b/bot/src/main.rs index 76c963dc..851a978e 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -53,12 +53,16 @@ async fn main() -> anyhow::Result<()> { } loop { - let e = azalea::SwarmBuilder::new() - .add_accounts(accounts.clone()) + // let e = azalea::SwarmBuilder::new() + // .add_accounts(accounts.clone()) + // .set_handler(handle) + // .set_swarm_handler(swarm_handle) + // .join_delay(Duration::from_millis(1000)) + // .start("localhost") + // .await; + let e = azalea::ClientBuilder::new() .set_handler(handle) - .set_swarm_handler(swarm_handle) - .join_delay(Duration::from_millis(1000)) - .start("localhost") + .start(Account::offline("bot"), "localhost") .await; println!("{e:?}"); }