1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00
azalea/bot/src/main.rs
mat 631ed63dbd
Swarm (#36)
* make azalea-pathfinder dir

* start writing d* lite impl

* more work on d* lite

* work more on implementing d* lite

* full d* lite impl

* updated edges

* add next() function

* add NoPathError

* why does dstar lite not work

* fix d* lite implementation

* make the test actually check the coords

* replace while loop with if statement

* fix clippy complaints

* make W only have to be PartialOrd

* fix PartialOrd issues

* implement mtd* lite

* add a test to mtd* lite

* remove normal d* lite

* make heuristic only take in one arg

* add `success` function

* Update README.md

* evil black magic to make .entity not need dimension

* start adding moves

* slightly improve the vec3/position situation

new macro that implements all the useful functions

* moves stuff

* make it compile

* update deps in az-pathfinder

* make it compile again

* more pathfinding stuff

* add Bot::look_at

* replace EntityMut and EntityRef with just Entity

* block pos pathfinding stuff

* rename movedirection to walkdirection

* execute path every tick

* advance path

* change az-pf version

* make azalea_client keep plugin state

* fix Plugins::get

* why does it think there is air

* start debugging incorrect air

* update some From methods to use rem_euclid

* start adding swarm

* fix deadlock

i still don't understand why it was happening but the solution was to keep the Client::player lock for shorter so it didn't overlap with the Client::dimension lock

* make lookat actually work probably

* fix going too fast

* Update main.rs

* make a thing immutable

* direction_looking_at

* fix rotations

* import swarm in an example

* fix stuff from merge

* remove azalea_pathfinder import

* delete azalea-pathfinder crate

already in azalea::pathfinder module

* swarms

* start working on shared dimensions

* Shared worlds work

* start adding Swarm::add_account

* add_account works

* change "client" to "bot" in some places

* Fix issues from merge

* Update world.rs

* add SwarmEvent::Disconnect(Account)

* almost add SwarmEvent::Chat and new plugin system

it panics rn

* make plugins have to provide the State associated type

* improve comments

* make fn build slightly cleaner

* fix SwarmEvent::Chat

* change a println in bot/main.rs

* Client::shutdown -> disconnect

* polish

fix clippy warnings + improve some docs a bit

* fix shared worlds*

*there's a bug that entities and bots will have their positions exaggerated because the relative movement packet is applied for every entity once per bot

* i am being trolled by rust

for some reason some stuff is really slow for literally no reason and it makes no sense i am going insane

* make world an RwLock again

* remove debug messages

* fix skipping event ticks

unfortunately now sending events is `.send().await?` instead of just `.send()`

* fix deadlock + warnings

* turns out my floor_mod impl was wrong

and i32::rem_euclid has the correct behavior LOL

* still errors with lots of bots

* make swarm iter & fix new chunks not loading

* improve docs

* start fixing tests

* fix all the tests

except the examples i don't know how to exclude them from the tests

* improve docs some more
2022-11-27 16:25:07 -06:00

161 lines
5.2 KiB
Rust

use azalea::pathfinder::BlockPosGoal;
// use azalea::ClientInformation;
use azalea::{prelude::*, BlockPos, Swarm, SwarmEvent, WalkDirection};
use azalea::{Account, Client, Event};
use azalea_protocol::packets::game::serverbound_client_command_packet::ServerboundClientCommandPacket;
use std::time::Duration;
#[derive(Default, Clone)]
struct State {}
#[derive(Default, Clone)]
struct SwarmState {}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::init();
{
use parking_lot::deadlock;
use std::thread;
use std::time::Duration;
// Create a background thread which checks for deadlocks every 10s
thread::spawn(move || loop {
thread::sleep(Duration::from_secs(10));
let deadlocks = deadlock::check_deadlock();
if deadlocks.is_empty() {
continue;
}
println!("{} deadlocks detected", deadlocks.len());
for (i, threads) in deadlocks.iter().enumerate() {
println!("Deadlock #{i}");
for t in threads {
println!("Thread Id {:#?}", t.thread_id());
println!("{:#?}", t.backtrace());
}
}
});
}
let mut accounts = Vec::new();
let mut states = Vec::new();
for i in 0..7 {
accounts.push(Account::offline(&format!("bot{}", i)));
states.push(State::default());
}
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)),
// join_delay: None,
})
.await;
println!("{e:?}");
}
}
async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<()> {
match event {
Event::Init => {
// bot.set_client_information(ClientInformation {
// view_distance: 2,
// ..Default::default()
// })
// .await?;
}
Event::Login => {
bot.chat("Hello world").await?;
}
Event::Chat(m) => {
if m.content() == bot.profile.name {
bot.chat("Bye").await?;
tokio::time::sleep(Duration::from_millis(50)).await;
bot.disconnect().await?;
}
let entity = bot
.world
.read()
.entity_by_uuid(&uuid::uuid!("6536bfed-8695-48fd-83a1-ecd24cf2a0fd"));
if let Some(entity) = entity {
if m.content() == "goto" {
let target_pos_vec3 = entity.pos();
let target_pos: BlockPos = target_pos_vec3.into();
bot.goto(BlockPosGoal::from(target_pos));
} else if m.content() == "look" {
let target_pos_vec3 = entity.pos();
let target_pos: BlockPos = target_pos_vec3.into();
println!("target_pos: {:?}", target_pos);
bot.look_at(&target_pos.center());
} else if m.content() == "jump" {
bot.set_jumping(true);
} else if m.content() == "walk" {
bot.walk(WalkDirection::Forward);
} else if m.content() == "stop" {
bot.set_jumping(false);
bot.walk(WalkDirection::None);
} else if m.content() == "lag" {
std::thread::sleep(Duration::from_millis(1000));
}
}
}
Event::Death(_) => {
bot.write_packet(ServerboundClientCommandPacket {
action: azalea_protocol::packets::game::serverbound_client_command_packet::Action::PerformRespawn,
}.get()).await?;
}
_ => {}
}
Ok(())
}
async fn swarm_handle(
mut swarm: Swarm<State>,
event: SwarmEvent,
_state: SwarmState,
) -> anyhow::Result<()> {
match &event {
SwarmEvent::Disconnect(account) => {
println!("bot got kicked! {}", account.username);
tokio::time::sleep(Duration::from_secs(5)).await;
swarm.add(account, State::default()).await?;
}
SwarmEvent::Chat(m) => {
println!("swarm chat message: {}", m.message().to_ansi(None));
if m.message().to_string() == "<py5> world" {
for (name, world) in &swarm.worlds.read().worlds {
println!("world name: {}", name);
if let Some(w) = world.upgrade() {
for chunk_pos in w.chunk_storage.read().chunks.values() {
println!("chunk: {:?}", chunk_pos);
}
} else {
println!("nvm world is gone");
}
}
}
if m.message().to_string() == "<py5> hi" {
for (bot, _) in swarm {
bot.chat("hello").await?;
}
}
}
_ => {}
}
Ok(())
}