mirror of
https://github.com/mat-1/azalea.git
synced 2024-09-20 07:02:31 +00:00
improve docs a bit more and delete potatobot example
This commit is contained in:
parent
f5ae1b9717
commit
758372f938
8 changed files with 12 additions and 133 deletions
|
@ -73,7 +73,7 @@ async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
|
||||||
|
|
||||||
# Swarms
|
# Swarms
|
||||||
|
|
||||||
Azalea lets you create "swarms", which are a group of bots in the same world that can perform actions together. See [testbot](https://github.com/mat-1/azalea/blob/main/azalea/examples/testbot.rs) for an example.
|
Azalea lets you create "swarms", which are a group of bots in the same world that can perform actions together. See [testbot](https://github.com/mat-1/azalea/blob/main/azalea/examples/testbot.rs) for an example. Also, if you're using swarms, you should also have both `azalea::prelude::*` and `azalea::swarm::prelude::*`.
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use azalea::prelude::*;
|
use azalea::{prelude::*, swarm::prelude::*};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
@ -10,7 +10,7 @@ async fn main() {
|
||||||
states.push(State::default());
|
states.push(State::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let e = azalea::SwarmBuilder::new()
|
let e = SwarmBuilder::new()
|
||||||
.add_accounts(accounts.clone())
|
.add_accounts(accounts.clone())
|
||||||
.set_handler(handle)
|
.set_handler(handle)
|
||||||
.set_swarm_handler(swarm_handle)
|
.set_swarm_handler(swarm_handle)
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
A relatively complex bot for farming potatoes.
|
|
||||||
|
|
||||||
Note: At the moment, all of the code here is only hypothetical. I decided to write this to help me decide how I want some the APIs to look.
|
|
||||||
|
|
||||||
## Attempted
|
|
||||||
- Sync: a sync function is called with the state and bot every time we get an event, and the function can queue events to execute at the end of the tick
|
|
||||||
|
|
||||||
Pros: No .lock().unwrap() necessary, and theoretically pausable by saving the state.
|
|
||||||
|
|
||||||
Cons: Async functions like opening containers and pathfinding are annoying because you have to keep state for them, and the code generally ends up being more confusing.
|
|
||||||
|
|
||||||
- Async non-blocking: an async function is called in a new task with the state mutex and bot every time we get an event
|
|
||||||
|
|
||||||
Pros: Easier to do async stuff like interacting with containers, code is somewhat easier to understand
|
|
||||||
|
|
||||||
Cons: Lock spam everywhere is annoying, and you have to make sure stuff doesn't accidentally run in parallel.
|
|
||||||
|
|
||||||
## Considered:
|
|
||||||
(I didn't actually try this because the problems were apparent)
|
|
||||||
- Async blocking: an async function is called with the state and bot every time we get an event, and only handles the next event when this one finishes running
|
|
||||||
|
|
||||||
Pros: No lock spam
|
|
||||||
|
|
||||||
Cons: Sometimes you want to handle multiple events at once like eating if you get hungry while pathfinding, this makes it harder without increasing complexity
|
|
|
@ -1,31 +0,0 @@
|
||||||
//! Automatically eat when we get hungry.
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use azalea::prelude::*;
|
|
||||||
use azalea::{Client, Event};
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
|
||||||
pub struct Plugin {
|
|
||||||
pub state: State,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Component)]
|
|
||||||
pub struct State {}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl azalea::PluginState for Plugin {
|
|
||||||
async fn handle(self: Box<Self>, event: Event, bot: Client) {
|
|
||||||
match event {
|
|
||||||
Event::UpdateHunger => {
|
|
||||||
if !bot.using_held_item() && bot.food_level() <= 17 {
|
|
||||||
if bot.hold(azalea::ItemGroup::Food).await {
|
|
||||||
bot.use_held_item().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
mod autoeat;
|
|
||||||
use azalea::prelude::*;
|
|
||||||
use azalea::{pathfinder, BlockPos, ItemKind, Vec3};
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
|
||||||
struct State {}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
let account = Account::offline("bot");
|
|
||||||
|
|
||||||
azalea::start(azalea::Options {
|
|
||||||
account,
|
|
||||||
address: "localhost",
|
|
||||||
state: State::default(),
|
|
||||||
plugins: plugins![autoeat::Plugin, pathfinder::Plugin],
|
|
||||||
handle,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
|
|
||||||
match event {
|
|
||||||
Event::Login => {
|
|
||||||
goto_farm(bot, state).await?;
|
|
||||||
// after we get to the farm, start farming
|
|
||||||
farm(bot, state).await?;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// go to the place where we start farming
|
|
||||||
async fn goto_farm(bot: Client, state: State) -> anyhow::Result<()> {
|
|
||||||
bot.goto(pathfinder::Goals::Near(5, BlockPos::new(0, 70, 0)))
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// go to the chest and deposit everything in our inventory.
|
|
||||||
async fn deposit(bot: &mut Client, state: State) -> anyhow::Result<()> {
|
|
||||||
// first throw away any garbage we might have
|
|
||||||
bot.toss(|item| item.kind != ItemKind::Potato && item.kind != ItemKind::DiamondHoe);
|
|
||||||
|
|
||||||
bot.goto(Vec3::new(0, 70, 0)).await?;
|
|
||||||
let chest = bot
|
|
||||||
.open_container(&bot.world.block_at(BlockPos::new(0, 70, 0)))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let inventory_potato_count: usize = bot
|
|
||||||
.inventory()
|
|
||||||
.count_total(|item| item.kind == ItemKind::Potato);
|
|
||||||
if inventory_potato_count > 64 {
|
|
||||||
chest
|
|
||||||
.deposit_total_count(
|
|
||||||
|item| item.kind == azalea::ItemKind::Potato,
|
|
||||||
inventory_potato_count - 64,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
chest.close().await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use azalea::entity::metadata::Player;
|
use azalea::entity::metadata::Player;
|
||||||
use azalea::{pathfinder, Account, Client, Event, GameProfileComponent, SwarmEvent};
|
use azalea::{pathfinder, Account, Client, Event, GameProfileComponent};
|
||||||
use azalea::{prelude::*, Swarm};
|
use azalea::{prelude::*, swarm::prelude::*};
|
||||||
use azalea_ecs::query::With;
|
use azalea_ecs::query::With;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -25,10 +25,10 @@ async fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Component, Default, Clone)]
|
||||||
struct State {}
|
struct State {}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Resource, Default, Clone)]
|
||||||
struct SwarmState {}
|
struct SwarmState {}
|
||||||
|
|
||||||
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
|
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
|
||||||
|
|
|
@ -29,7 +29,7 @@ use tokio::sync::mpsc;
|
||||||
/// A swarm is a way to conveniently control many bots at once, while also
|
/// 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.
|
/// being able to control bots at an individual level when desired.
|
||||||
///
|
///
|
||||||
/// Swarms are created from [`azalea::SwarmBuilder`].
|
/// Swarms are created from [`azalea::swarm::SwarmBuilder`].
|
||||||
///
|
///
|
||||||
/// The `S` type parameter is the type of the state for individual bots.
|
/// The `S` type parameter is the type of the state for individual bots.
|
||||||
/// It's used to make the [`Swarm::add`] function work.
|
/// It's used to make the [`Swarm::add`] function work.
|
||||||
|
|
3
azalea/src/swarm/prelude.rs
Normal file
3
azalea/src/swarm/prelude.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
//! A prelude that re-exports common swarm types in Azalea.
|
||||||
|
|
||||||
|
pub use crate::swarm::{Swarm, SwarmBuilder, SwarmEvent};
|
Loading…
Reference in a new issue