2021-12-16 05:10:55 +00:00
|
|
|
# Azalea
|
|
|
|
|
2021-12-20 21:22:02 +00:00
|
|
|
A Rust library for creating Minecraft bots.
|
|
|
|
|
|
|
|
I named this Azalea because it sounds like a cool word and this is a cool library. This project was heavily inspired by PrismarineJS.
|
2021-12-16 05:26:15 +00:00
|
|
|
|
|
|
|
## Goals
|
|
|
|
|
2021-12-16 20:25:02 +00:00
|
|
|
- Do everything a vanilla client can do
|
2021-12-20 19:36:20 +00:00
|
|
|
- Be easy to use
|
2022-04-19 03:38:53 +00:00
|
|
|
- Bypass most/all anticheats
|
|
|
|
- Support the latest Minecraft version
|
|
|
|
- Be fast
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
## Example code
|
|
|
|
|
2022-04-28 22:50:39 +00:00
|
|
|
Note that these doesn't work yet, it's just how I want the API to look.
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
```rs
|
2022-04-29 05:40:47 +00:00
|
|
|
use azalea::{Account, Event};
|
2022-04-25 16:18:12 +00:00
|
|
|
|
2022-04-29 05:40:47 +00:00
|
|
|
let account = Account::offline("bot");
|
|
|
|
// or let account = azalea::Account::microsoft("access token").await;
|
2022-04-25 16:18:12 +00:00
|
|
|
|
2022-04-29 05:40:47 +00:00
|
|
|
let bot = account.join("localhost".try_into().unwrap()).await.unwrap();
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
loop {
|
2022-04-29 05:40:47 +00:00
|
|
|
match bot.next().await {
|
2022-04-25 16:18:12 +00:00
|
|
|
Event::Message(m) {
|
|
|
|
if m.username == bot.username { return };
|
|
|
|
bot.chat(m.message).await;
|
|
|
|
},
|
|
|
|
Event::Kicked(m) {
|
|
|
|
println!(m);
|
|
|
|
bot.reconnect().await.unwrap();
|
|
|
|
},
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-04-28 22:50:39 +00:00
|
|
|
```rs
|
|
|
|
use azalea::{Bot, Event};
|
|
|
|
|
|
|
|
let bot = Bot::offline("bot");
|
|
|
|
// or let bot = azalea::Bot::microsoft("access token").await;
|
|
|
|
|
|
|
|
bot.join("localhost".try_into().unwrap()).await.unwrap();
|
|
|
|
|
|
|
|
loop {
|
|
|
|
match bot.recv().await {
|
|
|
|
Event::Message(m) {
|
|
|
|
if m.username == bot.username { return };
|
|
|
|
if m.message = "go" {
|
|
|
|
bot.goto_goal(
|
|
|
|
pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0))
|
|
|
|
).await;
|
|
|
|
let chest = bot.open_chest(&bot.world.find_one_block(|b| b.id == "minecraft:chest")).await.unwrap();
|
|
|
|
bot.take_amount(&chest, 3, |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();
|
|
|
|
bot.craft(&crafting_table, &bot.recipe_for("minecraft:sticks")).await?;
|
|
|
|
let pickaxe = bot.craft(&crafting_table, &bot.recipe_for("minecraft:wooden_pickaxe")).await?;
|
|
|
|
crafting_table.close().await;
|
|
|
|
|
|
|
|
bot.hold(&pickaxe);
|
|
|
|
loop {
|
|
|
|
if let Err(e) = bot.dig(bot.feet_coords().down(1)).await {
|
|
|
|
println!("{:?}", e);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-04-25 16:18:12 +00:00
|
|
|
You can use the `azalea::Bots` struct to control many bots as one unit.
|
|
|
|
|
|
|
|
```rs
|
2022-04-29 05:40:47 +00:00
|
|
|
use azalea::{Account, Accounts, Event, pathfinder};
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
2022-04-29 05:40:47 +00:00
|
|
|
let accounts = Accounts::new();
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
for i in 0..10 {
|
2022-04-29 05:40:47 +00:00
|
|
|
accounts.add(Account::offline(format!("bot{}", i)));
|
2022-04-25 16:18:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 05:40:47 +00:00
|
|
|
let bots = accounts.join("localhost".try_into().unwrap()).await.unwrap();
|
2022-04-25 16:18:12 +00:00
|
|
|
|
2022-04-28 22:50:39 +00:00
|
|
|
bots.goto(azalea::BlockCoord(0, 70, 0)).await;
|
|
|
|
// or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockCoord(0, 70, 0))).await;
|
2022-04-25 16:18:12 +00:00
|
|
|
|
|
|
|
// destroy the blocks in this area and then leave
|
|
|
|
|
|
|
|
bots.fill(
|
2022-04-28 22:50:39 +00:00
|
|
|
azalea::Selection::Range(
|
|
|
|
azalea::BlockCoord(0, 0, 0),
|
|
|
|
azalea::BlockCoord(16, 255, 16)
|
2022-04-25 16:18:12 +00:00
|
|
|
),
|
|
|
|
azalea::block::Air
|
|
|
|
).await;
|
|
|
|
}
|
|
|
|
```
|