Add bad pathfinding

This commit is contained in:
ErrorNoInternet 2023-01-08 18:30:36 +08:00
parent ec14807126
commit cbe6c96ca1
Signed by untrusted user who does not match committer: ErrorNoInternet
GPG Key ID: 2486BFB7B1E6A4A3
4 changed files with 306 additions and 15 deletions

1
Cargo.lock generated

@ -598,6 +598,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"azalea",
"azalea-block",
"azalea-protocol",
"colored",
"serde",

@ -4,8 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
azalea-protocol = "0.5.0"
azalea = "0.5.0"
azalea-protocol = "0.5.0"
azalea-block = "0.5.0"
toml = "0.5.10"
serde = { version = "1.0", features = ["derive"] }
tokio = "1.24.1"

81
src/bot.rs Normal file

@ -0,0 +1,81 @@
use crate::State;
use azalea::prelude::*;
#[derive(PartialEq, PartialOrd)]
pub enum Command {
Location,
Goto,
Stop,
Unknown,
}
pub fn process_command(command: &String, _client: &Client, state: &mut State) -> String {
let check_command = |command: &mut Command, segment: &String| {
match command {
Command::Location => return format!("{} is somewhere", segment),
Command::Goto => {
if state.final_target.lock().unwrap().is_some()
&& state.final_target.lock().unwrap().clone().unwrap().len() == 3
{
*command = Command::Unknown;
let coordinates =
(*state.final_target.lock().unwrap().clone().unwrap()).to_vec();
return format!(
"I am now going to {} {} {}...",
coordinates[0], coordinates[1], coordinates[2]
);
}
if state.final_target.lock().unwrap().is_none() {
*state.final_target.lock().unwrap() = Some(Vec::new());
};
let mut new_coordinates = state.final_target.lock().unwrap().clone().unwrap();
new_coordinates.push(segment.parse().unwrap_or(0));
*state.final_target.lock().unwrap() = Some(new_coordinates);
return "".to_string();
}
Command::Stop => {
*state.final_target.lock().unwrap() = None;
*command = Command::Unknown;
return "I am no longer doing anything".to_string();
}
_ => {
*command = Command::Unknown;
return "".to_string();
}
};
};
let segments: Vec<String> = command
.split(" ")
.map(|segment| segment.to_string())
.collect();
if segments.len() <= 0 {
return "Hmm... I was unable to parse your command!".to_string();
};
let mut command = Command::Unknown;
for (_index, segment) in segments.iter().enumerate() {
match segment.to_lowercase().as_str() {
"location" => command = Command::Location,
"goto" => command = Command::Goto,
"stop" => command = Command::Stop,
_ => {
let return_value = check_command(&mut command, &segment);
if !return_value.is_empty() {
return return_value;
}
}
};
}
if command != Command::Unknown {
let return_value = check_command(&mut command, &"".to_string());
if !return_value.is_empty() {
return return_value;
}
}
"Sorry, I don't know what you mean...".to_string()
}

@ -1,14 +1,27 @@
mod bot;
mod logging;
use azalea::pathfinder::BlockPosGoal;
use azalea::{prelude::*, BlockPos, ClientInformation};
use azalea_block::BlockState;
use azalea_protocol::packets::game::serverbound_client_command_packet::{
Action::PerformRespawn, ServerboundClientCommandPacket,
};
use azalea_protocol::ServerAddress;
use logging::LogMessageType::*;
use logging::{log_error, log_message};
use azalea::prelude::*;
use azalea_protocol::ServerAddress;
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
static NON_SOLID_BLOCKS: &[BlockState] = &[
BlockState::Air,
BlockState::Lava__0,
BlockState::Water__0,
BlockState::Cobweb,
BlockState::Grass,
BlockState::Fern,
BlockState::DeadBush,
];
#[derive(Debug, Clone, Deserialize, Serialize)]
struct BotConfiguration {
@ -18,6 +31,7 @@ struct BotConfiguration {
register_command: String,
login_keyword: String,
login_command: String,
bot_owners: Vec<String>,
}
impl Default for BotConfiguration {
@ -29,6 +43,7 @@ impl Default for BotConfiguration {
register_command: "register 1VerySafePassword!!! 1VerySafePassword!!!".to_string(),
login_keyword: "/login".to_string(),
login_command: "login 1VerySafePassword!!!".to_string(),
bot_owners: vec![],
}
}
}
@ -84,7 +99,13 @@ async fn main() {
return;
}
},
state: State { bot_configuration },
state: State {
bot_configuration,
tick_counter: Arc::new(Mutex::new(0)),
pathfind_tick_counter: Arc::new(Mutex::new(0)),
final_target: Arc::new(Mutex::new(None)),
current_target: Arc::new(Mutex::new(None)),
},
plugins: plugins![],
handle,
})
@ -98,16 +119,33 @@ async fn main() {
#[derive(Default, Clone)]
pub struct State {
bot_configuration: BotConfiguration,
tick_counter: Arc<Mutex<u8>>,
pathfind_tick_counter: Arc<Mutex<u8>>,
final_target: Arc<Mutex<Option<Vec<i32>>>>,
current_target: Arc<Mutex<Option<Vec<i32>>>>,
}
async fn handle(client: Client, event: Event, state: State) -> anyhow::Result<()> {
async fn handle(client: Client, event: Event, mut state: State) -> anyhow::Result<()> {
match event {
Event::Login => log_message(
Bot,
&"ErrorNoWatcher has successfully joined the server".to_string(),
),
Event::Login => {
log_message(
Bot,
&"ErrorNoWatcher has successfully joined the server".to_string(),
);
log_error(
client
.set_client_information(ClientInformation {
view_distance: 2,
..Default::default()
})
.await,
);
}
Event::Death(_) => {
log_message(Bot, "Player has died! Automatically respawning...");
log_message(
Bot,
&"Player has died! Automatically respawning...".to_string(),
);
client
.write_packet(
ServerboundClientCommandPacket {
@ -117,12 +155,145 @@ async fn handle(client: Client, event: Event, state: State) -> anyhow::Result<()
)
.await?
}
Event::Tick => {
*state.tick_counter.lock().unwrap() += 1;
*state.pathfind_tick_counter.lock().unwrap() += 1;
if *state.tick_counter.lock().unwrap() >= 20 {
*state.tick_counter.lock().unwrap() = 0;
if state.current_target.lock().unwrap().is_some() {
let coordinates =
(*state.current_target.lock().unwrap().clone().unwrap()).to_vec();
println!("{:?}", coordinates);
client.goto(BlockPosGoal {
pos: BlockPos {
x: coordinates[0],
y: coordinates[1],
z: coordinates[2],
},
});
}
}
if *state.pathfind_tick_counter.lock().unwrap() >= 10 {
*state.pathfind_tick_counter.lock().unwrap() = 0;
if state.final_target.lock().unwrap().is_some() {
let current_position = client.entity().pos().clone();
let target_position =
state.final_target.lock().unwrap().clone().unwrap().to_vec();
let mut new_position = Vec::new();
if (current_position.x as i32) < target_position[0] {
new_position.push(current_position.x as i32 + 2);
} else {
new_position.push(current_position.x as i32 - 2);
}
new_position.push(current_position.y as i32 + 2);
if (current_position.z as i32) < target_position[2] {
new_position.push(current_position.z as i32 + 2);
} else {
new_position.push(current_position.z as i32 - 2);
}
while NON_SOLID_BLOCKS.to_vec().contains(
&client
.world
.read()
.get_block_state(&BlockPos {
x: new_position[0],
y: new_position[1] - 1,
z: new_position[2],
})
.unwrap(),
) {
new_position[1] -= 1;
}
while !NON_SOLID_BLOCKS.to_vec().contains(
&client
.world
.read()
.get_block_state(&BlockPos {
x: new_position[0],
y: new_position[1],
z: new_position[2],
})
.unwrap(),
) {
if new_position[0] < target_position[0] {
new_position[0] += 1
} else {
new_position[0] -= 1
}
}
while !NON_SOLID_BLOCKS.to_vec().contains(
&client
.world
.read()
.get_block_state(&BlockPos {
x: new_position[0],
y: new_position[1],
z: new_position[2],
})
.unwrap(),
) {
if new_position[2] < target_position[2] {
new_position[2] += 1
} else {
new_position[2] -= 1
}
}
while NON_SOLID_BLOCKS.to_vec().contains(
&client
.world
.read()
.get_block_state(&BlockPos {
x: new_position[0],
y: new_position[1] - 1,
z: new_position[2],
})
.unwrap(),
) {
if new_position[0] < target_position[0] {
new_position[0] += 1
} else {
new_position[0] -= 1
}
}
while NON_SOLID_BLOCKS.to_vec().contains(
&client
.world
.read()
.get_block_state(&BlockPos {
x: new_position[0],
y: new_position[1] - 1,
z: new_position[2],
})
.unwrap(),
) {
if new_position[2] < target_position[2] {
new_position[2] += 1
} else {
new_position[2] -= 1
}
}
*state.current_target.lock().unwrap() = Some(new_position);
}
}
}
Event::Chat(message) => {
let message_text = message.message().to_ansi();
log_message(Chat, &message_text);
log_message(Chat, &message.message().to_ansi());
if message.username().is_none() {
if message_text.contains(&state.bot_configuration.register_keyword) {
if message
.content()
.contains(&state.bot_configuration.register_keyword)
{
log_message(
Bot,
&"Detected register keyword! Registering...".to_string(),
@ -132,7 +303,10 @@ async fn handle(client: Client, event: Event, state: State) -> anyhow::Result<()
.send_command_packet(&state.bot_configuration.register_command)
.await,
)
} else if message_text.contains(&state.bot_configuration.login_keyword) {
} else if message
.content()
.contains(&state.bot_configuration.login_keyword)
{
log_message(Bot, &"Detected login keyword! Logging in...".to_string());
log_error(
client
@ -140,6 +314,40 @@ async fn handle(client: Client, event: Event, state: State) -> anyhow::Result<()
.await,
)
}
return Ok(());
}
for bot_owner in state.bot_configuration.bot_owners.clone() {
if message
.message()
.to_string()
.starts_with(&format!("{} whispers to you: ", bot_owner))
{
let command = message
.message()
.to_string()
.split("whispers to you: ")
.nth(1)
.unwrap_or("")
.to_string();
log_error(
client
.send_command_packet(&format!(
"msg {} Processing command...",
bot_owner
))
.await,
);
log_error(
client
.send_command_packet(&format!(
"msg {} {}",
bot_owner,
&bot::process_command(&command, &client, &mut state),
))
.await,
);
}
}
}
_ => {}