diff --git a/azalea/examples/craft_dig_straight_down.rs b/azalea/examples/craft_dig_straight_down.rs index 76979406..0632776e 100755 --- a/azalea/examples/craft_dig_straight_down.rs +++ b/azalea/examples/craft_dig_straight_down.rs @@ -3,7 +3,7 @@ use azalea::prelude::*; use parking_lot::Mutex; use std::sync::Arc; -#[derive(Default, Clone)] +#[derive(Default, Clone, Component)] struct State { pub started: Arc>, } @@ -13,15 +13,11 @@ async fn main() { let account = Account::offline("bot"); // or let bot = Account::microsoft("email").await; - azalea::start(azalea::Options { - account, - address: "localhost", - state: State::default(), - plugins: plugins![], - handle, - }) - .await - .unwrap(); + azalea::ClientBuilder::new() + .set_handler(handle) + .start(account, "localhost") + .await + .unwrap(); } async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { diff --git a/azalea/examples/echo.rs b/azalea/examples/echo.rs index f9bafebd..292e12cd 100755 --- a/azalea/examples/echo.rs +++ b/azalea/examples/echo.rs @@ -7,15 +7,11 @@ async fn main() { let account = Account::offline("bot"); // or let account = Account::microsoft("email").await; - azalea::start(azalea::Options { - account, - address: "localhost", - state: State::default(), - plugins: plugins![], - handle, - }) - .await - .unwrap(); + ClientBuilder::new() + .set_handler(handle) + .start(account, "localhost") + .await + .unwrap(); } #[derive(Default, Clone, Component)] @@ -28,7 +24,7 @@ async fn handle(bot: Client, event: Event, _state: State) -> anyhow::Result<()> if sender == bot.profile.name { return Ok(()); // ignore our own messages } - bot.chat(&content).await?; + bot.chat(&content); }; } _ => {} diff --git a/azalea/examples/matbot.rs b/azalea/examples/matbot.rs index 17736eab..1ddd9197 100644 --- a/azalea/examples/matbot.rs +++ b/azalea/examples/matbot.rs @@ -14,7 +14,7 @@ use std::time::Duration; #[derive(Default, Clone, Component)] struct State {} -#[derive(Default, Clone, Component)] +#[derive(Default, Clone, Resource)] struct SwarmState {} #[tokio::main] @@ -54,7 +54,7 @@ async fn main() -> anyhow::Result<()> { } loop { - let e = azalea::SwarmBuilder::new() + let e = SwarmBuilder::new() .add_accounts(accounts.clone()) .set_handler(handle) .set_swarm_handler(swarm_handle) diff --git a/azalea/examples/mine_a_chunk.rs b/azalea/examples/mine_a_chunk.rs index 72d27ff3..bc4e4fdd 100644 --- a/azalea/examples/mine_a_chunk.rs +++ b/azalea/examples/mine_a_chunk.rs @@ -1,5 +1,4 @@ -use azalea::{prelude::*, SwarmEvent}; -use azalea::{Account, Client, Event, Swarm}; +use azalea::prelude::*; #[tokio::main] async fn main() { @@ -7,44 +6,29 @@ async fn main() { let mut states = Vec::new(); for i in 0..10 { - accounts.push(Account::offline(&format!("bot{o}"))); + accounts.push(Account::offline(&format!("bot{i}"))); states.push(State::default()); } - azalea::start_swarm(azalea::SwarmOptions { - accounts, - address: "localhost", - - swarm_state: SwarmState::default(), - states, - - swarm_plugins: plugins![], - plugins: plugins![], - - handle, - swarm_handle, - - join_delay: None, - }) - .await - .unwrap(); + let e = azalea::SwarmBuilder::new() + .add_accounts(accounts.clone()) + .set_handler(handle) + .set_swarm_handler(swarm_handle) + .start("localhost") + .await; } -#[derive(Default, Clone)] +#[derive(Default, Clone, Component)] struct State {} -#[derive(Default, Clone)] +#[derive(Default, Clone, Resource)] struct SwarmState {} async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { Ok(()) } -async fn swarm_handle( - swarm: Swarm, - event: SwarmEvent, - state: SwarmState, -) -> anyhow::Result<()> { +async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { match &event { SwarmEvent::Login => { swarm.goto(azalea::BlockPos::new(0, 70, 0)).await; diff --git a/azalea/examples/pvp.rs b/azalea/examples/pvp.rs index 28e54f35..be818024 100755 --- a/azalea/examples/pvp.rs +++ b/azalea/examples/pvp.rs @@ -1,5 +1,9 @@ -use azalea::{pathfinder, Account, Client, Event, SwarmEvent}; +use std::time::Duration; + +use azalea::entity::metadata::Player; +use azalea::{pathfinder, Account, Client, Event, GameProfileComponent, SwarmEvent}; use azalea::{prelude::*, Swarm}; +use azalea_ecs::query::With; #[tokio::main] async fn main() { @@ -11,23 +15,14 @@ async fn main() { states.push(State::default()); } - azalea::start_swarm(azalea::SwarmOptions { - accounts, - address: "localhost", - - swarm_state: SwarmState::default(), - states, - - swarm_plugins: swarm_plugins![pathfinder::Plugin], - plugins: plugins![], - - handle, - swarm_handle, - - join_delay: None, - }) - .await - .unwrap(); + SwarmBuilder::new() + .add_accounts(accounts.clone()) + .set_handler(handle) + .set_swarm_handler(swarm_handle) + .join_delay(Duration::from_millis(1000)) + .start("localhost") + .await + .unwrap(); } #[derive(Default, Clone)] @@ -39,15 +34,13 @@ struct SwarmState {} async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { Ok(()) } -async fn swarm_handle( - swarm: Swarm, - event: SwarmEvent, - state: SwarmState, -) -> anyhow::Result<()> { +async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { match event { SwarmEvent::Tick => { if let Some(target_entity) = - swarm.entity_by::(|name: &Name| name == "Herobrine") + swarm.entity_by::>(|profile: &&GameProfileComponent| { + profile.name == "Herobrine" + }) { let target_bounding_box = swarm.map_entity(target_entity, |bb: &BoundingBox| bb.clone()); diff --git a/azalea/src/prelude.rs b/azalea/src/prelude.rs index 3d8cc13e..a26f72d1 100644 --- a/azalea/src/prelude.rs +++ b/azalea/src/prelude.rs @@ -3,5 +3,7 @@ pub use crate::bot::BotClientExt; pub use crate::pathfinder::PathfinderClientExt; +pub use crate::{ClientBuilder, SwarmBuilder}; pub use azalea_client::{Account, Client, Event}; pub use azalea_ecs::component::Component; +pub use azalea_ecs::system::Resource; diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs index 9c16bc01..64312579 100644 --- a/azalea/src/swarm/mod.rs +++ b/azalea/src/swarm/mod.rs @@ -28,12 +28,10 @@ use tokio::sync::mpsc; /// A swarm is a way to conveniently control many bots at once, while also /// being able to control bots at an individual level when desired. /// -/// Swarms are created from the [`azalea::start_swarm`] function. +/// Swarms are created from [`azalea::SwarmBuilder`]. /// /// The `S` type parameter is the type of the state for individual bots. /// It's used to make the [`Swarm::add`] function work. -/// -/// [`azalea::start_swarm`]: fn.start_swarm.html #[derive(Clone, Resource)] pub struct Swarm { pub ecs_lock: Arc>, @@ -84,7 +82,7 @@ where Fut: Future> + Send + 'static, SwarmFut: Future> + Send + 'static, S: Default + Send + Sync + Clone + Component + 'static, - SS: Default + Send + Sync + Clone + Component + 'static, + SS: Default + Send + Sync + Clone + Resource + 'static, { /// Start creating the swarm. #[must_use] @@ -297,7 +295,7 @@ where Fut: Future> + Send + 'static, SwarmFut: Future> + Send + 'static, S: Default + Send + Sync + Clone + Component + 'static, - SS: Default + Send + Sync + Clone + Component + 'static, + SS: Default + Send + Sync + Clone + Resource + 'static, { fn default() -> Self { Self::new() @@ -340,13 +338,12 @@ pub enum SwarmStartError { /// # Examples /// ```rust,no_run /// use azalea::{prelude::*, Swarm, SwarmEvent}; -/// use azalea::{Account, Client, Event}; /// use std::time::Duration; /// -/// #[derive(Default, Clone)] +/// #[derive(Default, Clone, Component)] /// struct State {} /// -/// #[derive(Default, Clone)] +/// #[derive(Default, Clone, Resource)] /// struct SwarmState {} /// /// #[tokio::main] @@ -360,22 +357,13 @@ pub enum SwarmStartError { /// } /// /// loop { -/// let e = azalea::start_swarm(azalea::SwarmOptions { -/// accounts: accounts.clone(), -/// address: "localhost", -/// -/// states: states.clone(), -/// swarm_state: SwarmState::default(), -/// -/// plugins: plugins![], -/// swarm_plugins: swarm_plugins![], -/// -/// handle, -/// swarm_handle, -/// -/// join_delay: Some(Duration::from_millis(1000)), -/// }) -/// .await; +/// let e = SwarmBuilder::new() +/// .add_accounts(accounts.clone()) +/// .set_handler(handle) +/// .set_swarm_handler(swarm_handle) +/// .join_delay(Duration::from_millis(1000)) +/// .start("localhost") +/// .await; /// println!("{e:?}"); /// } /// } @@ -405,16 +393,6 @@ pub enum SwarmStartError { /// } /// Ok(()) /// } -// pub async fn start_swarm< -// S: Send + Sync + Clone + 'static, -// SS: Send + Sync + Clone + 'static, -// A: Send + TryInto, -// Fut: Future> + Send + 'static, -// SwarmFut: Future> + Send + 'static, -// >( -// options: SwarmOptions, -// ) -> Result<(), SwarmStartError> { -// } impl Swarm { /// Add a new account to the swarm. You can remove it later by calling @@ -457,7 +435,7 @@ impl Swarm { tokio::spawn(async move { while let Some(event) = rx.recv().await { // we can't handle events here (since we can't copy the handler), - // they're handled above in start_swarm + // they're handled above in SwarmBuilder::start if let Err(e) = cloned_bots_tx.send((Some(event), cloned_bot.clone())) { error!("Error sending event to swarm: {e}"); }