aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCargo.lock14
-rw-r--r--azalea-block/src/lib.rs7
-rw-r--r--azalea/Cargo.toml6
-rw-r--r--azalea/examples/craft_dig_straight_down.rs (renamed from examples/craft_dig_straight_down.rs)3
-rw-r--r--azalea/examples/echo.rs (renamed from examples/echo.rs)0
-rw-r--r--azalea/examples/mine_a_chunk.rs (renamed from examples/mine_a_chunk.rs)8
-rw-r--r--azalea/examples/potatobot/README.md24
-rw-r--r--azalea/examples/potatobot/autoeat.rs20
-rw-r--r--azalea/examples/potatobot/main.rs91
-rw-r--r--azalea/examples/pvp.rs (renamed from examples/pvp.rs)0
-rw-r--r--azalea/src/lib.rs16
11 files changed, 163 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4c50a8c7..9d1ba73f 100755
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -101,6 +101,11 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "azalea"
version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "env_logger",
+ "tokio",
+]
[[package]]
name = "azalea-auth"
@@ -890,9 +895,9 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
+checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [
"libc",
"log",
@@ -1432,10 +1437,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
-version = "1.19.2"
+version = "1.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
+checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95"
dependencies = [
+ "autocfg",
"bytes",
"libc",
"memchr",
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs
index 969288f5..cc7ddf73 100644
--- a/azalea-block/src/lib.rs
+++ b/azalea-block/src/lib.rs
@@ -66,7 +66,10 @@ mod tests {
#[test]
fn test_from_blockstate() {
- let box_block: Box<dyn Block> = Box::<dyn Block>::from(BlockState::Air);
- assert_eq!(box_block.id(), "air");
+ let block: Box<dyn Block> = Box::<dyn Block>::from(BlockState::Air);
+ assert_eq!(block.id(), "air");
+
+ let block: Box<dyn Block> = Box::<dyn Block>::from(BlockState::FloweringAzalea);
+ assert_eq!(block.id(), "flowering_azalea");
}
}
diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml
index 7f6aeb9f..0256194e 100644
--- a/azalea/Cargo.toml
+++ b/azalea/Cargo.toml
@@ -9,3 +9,9 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+
+
+[dev-dependencies]
+tokio = "^1.21.1"
+env_logger = "^0.9.1"
+anyhow = "^1.0.65"
diff --git a/examples/craft_dig_straight_down.rs b/azalea/examples/craft_dig_straight_down.rs
index 47c4fe28..53e5cae8 100644
--- a/examples/craft_dig_straight_down.rs
+++ b/azalea/examples/craft_dig_straight_down.rs
@@ -30,12 +30,11 @@ async fn handle_event(event: &Event, bot: &Bot, ctx: Arc<Context>) {
ctx_lock.started = true;
drop(ctx_lock);
- bot.goto_goal(
+ bot.goto(
pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0))
).await;
let chest = bot.open_container(&bot.world.find_one_block(|b| b.id == "minecraft:chest")).await.unwrap();
bot.take_amount(&chest, 5, |i| i.id == "#minecraft:planks").await;
- // when rust adds async drop this won't be necessary
chest.close().await;
let crafting_table = bot.open_crafting_table(&bot.world.find_one_block(|b| b.id == "minecraft:crafting_table")).await.unwrap();
diff --git a/examples/echo.rs b/azalea/examples/echo.rs
index c9e46a09..c9e46a09 100644
--- a/examples/echo.rs
+++ b/azalea/examples/echo.rs
diff --git a/examples/mine_a_chunk.rs b/azalea/examples/mine_a_chunk.rs
index bb85a637..6549f2b2 100644
--- a/examples/mine_a_chunk.rs
+++ b/azalea/examples/mine_a_chunk.rs
@@ -12,15 +12,15 @@ async fn main() {
let bots = accounts.join("localhost".try_into().unwrap()).await.unwrap();
- bots.goto(azalea::BlockCoord(0, 70, 0)).await;
- // or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockCoord(0, 70, 0))).await;
+ bots.goto(azalea::BlockPos::new(0, 70, 0)).await;
+ // or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockPos(0, 70, 0))).await;
// destroy the blocks in this area and then leave
bots.fill(
azalea::Selection::Range(
- azalea::BlockCoord(0, 0, 0),
- azalea::BlockCoord(16, 255, 16)
+ azalea::BlockPos::new(0, 0, 0),
+ azalea::BlockPos::new(16, 255, 16)
),
azalea::block::Air
).await;
diff --git a/azalea/examples/potatobot/README.md b/azalea/examples/potatobot/README.md
new file mode 100644
index 00000000..e494316e
--- /dev/null
+++ b/azalea/examples/potatobot/README.md
@@ -0,0 +1,24 @@
+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
diff --git a/azalea/examples/potatobot/autoeat.rs b/azalea/examples/potatobot/autoeat.rs
new file mode 100644
index 00000000..44702295
--- /dev/null
+++ b/azalea/examples/potatobot/autoeat.rs
@@ -0,0 +1,20 @@
+//! Automatically eat when we get hungry.
+
+use azalea::{Client, Event};
+use std::sync::{Arc, Mutex};
+
+#[derive(Default)]
+pub struct State {}
+
+pub async fn handle(bot: &mut Client, event: Event, state: Arc<Mutex<State>>) {
+ 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;
+ }
+ }
+ }
+ _ => {}
+ }
+}
diff --git a/azalea/examples/potatobot/main.rs b/azalea/examples/potatobot/main.rs
new file mode 100644
index 00000000..94ed0005
--- /dev/null
+++ b/azalea/examples/potatobot/main.rs
@@ -0,0 +1,91 @@
+mod autoeat;
+
+use azalea::{pathfinder, Account, BlockPos, Client, Event, ItemKind, MoveDirection, Vec3};
+use std::{
+ convert::TryInto,
+ sync::{Arc, Mutex},
+};
+
+#[derive(Default)]
+struct State {
+ pub eating: bool,
+}
+
+#[tokio::main]
+async fn main() {
+ env_logger::init();
+
+ let account = Account::offline("bot");
+ let (bot, mut rx) = account
+ .join(&"localhost".try_into().unwrap())
+ .await
+ .unwrap();
+
+ // Maybe all this could be turned into a macro in the future?
+ let state = Arc::new(Mutex::new(State::default()));
+ let autoeat_state = Arc::new(Mutex::new(autoeat::State::default()));
+ let pathfinder_state = Arc::new(Mutex::new(pathfinder::State::default()));
+ while let Some(event) = rx.recv().await {
+ // we put it into an Arc so it's cheaper to clone
+ let event = Arc::new(event);
+
+ tokio::spawn(autoeat::handle(
+ bot.clone(),
+ event.clone(),
+ autoeat_state.clone(),
+ ));
+ tokio::spawn(pathfinder::handle(
+ bot.clone(),
+ event.clone(),
+ pathfinder_state.clone(),
+ ));
+ tokio::spawn(handle(bot.clone(), event.clone(), state.clone()));
+ }
+}
+
+async fn handle(bot: Client, event: Event, state: Arc<Mutex<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: Arc<Mutex<State>>) -> anyhow::Result<()> {
+ bot.state
+ .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: &mut Arc<Mutex<State>>) -> anyhow::Result<()> {
+ // first throw away any garbage we might have
+ bot.toss(|item| item.kind != ItemKind::Potato && item.kind != ItemKind::DiamondHoe);
+
+ bot.state.goto(Vec3::new(0, 70, 0)).await?;
+ let chest = bot
+ .open_container(&bot.dimension.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(())
+}
diff --git a/examples/pvp.rs b/azalea/examples/pvp.rs
index 5febdd45..5febdd45 100644
--- a/examples/pvp.rs
+++ b/azalea/examples/pvp.rs
diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs
index 7d12d9af..144caa55 100644
--- a/azalea/src/lib.rs
+++ b/azalea/src/lib.rs
@@ -1,14 +1,2 @@
-pub fn add(left: usize, right: usize) -> usize {
- left + right
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn it_works() {
- let result = add(2, 2);
- assert_eq!(result, 4);
- }
-}
+//! This is currently an advertisement crate for
+//! [Azalea](https://github.com/mat-1/azalea). More stuff will be here soon!