More new commands
This commit is contained in:
parent
eb81844ee5
commit
3977d83ade
221
src/bot.rs
221
src/bot.rs
@ -1,5 +1,5 @@
|
|||||||
use crate::{logging::log_error, State};
|
use crate::{logging::log_error, State};
|
||||||
use azalea::{pathfinder::BlockPosGoal, prelude::*, BlockPos};
|
use azalea::{pathfinder::BlockPosGoal, prelude::*, BlockPos, SprintDirection, WalkDirection};
|
||||||
use azalea_protocol::packets::game::{
|
use azalea_protocol::packets::game::{
|
||||||
self, serverbound_interact_packet::InteractionHand, ServerboundGamePacket,
|
self, serverbound_interact_packet::InteractionHand, ServerboundGamePacket,
|
||||||
};
|
};
|
||||||
@ -26,6 +26,12 @@ pub enum Command {
|
|||||||
Look,
|
Look,
|
||||||
Sneak,
|
Sneak,
|
||||||
Unsneak,
|
Unsneak,
|
||||||
|
Interact,
|
||||||
|
Attack,
|
||||||
|
Walk,
|
||||||
|
Sprint,
|
||||||
|
DropItem,
|
||||||
|
DropStack,
|
||||||
ToggleBotStatusMessages,
|
ToggleBotStatusMessages,
|
||||||
ToggleAlertMessages,
|
ToggleAlertMessages,
|
||||||
Unknown,
|
Unknown,
|
||||||
@ -64,6 +70,12 @@ pub async fn process_command(
|
|||||||
"look" => command = Command::Look,
|
"look" => command = Command::Look,
|
||||||
"sneak" => command = Command::Sneak,
|
"sneak" => command = Command::Sneak,
|
||||||
"unsneak" => command = Command::Unsneak,
|
"unsneak" => command = Command::Unsneak,
|
||||||
|
"interact" => command = Command::Interact,
|
||||||
|
"attack" => command = Command::Attack,
|
||||||
|
"walk" => command = Command::Walk,
|
||||||
|
"sprint" => command = Command::Sprint,
|
||||||
|
"drop_item" => command = Command::DropItem,
|
||||||
|
"drop_stack" => command = Command::DropStack,
|
||||||
"toggle_alert_messages" => command = Command::ToggleAlertMessages,
|
"toggle_alert_messages" => command = Command::ToggleAlertMessages,
|
||||||
"toggle_bot_status_messages" => command = Command::ToggleBotStatusMessages,
|
"toggle_bot_status_messages" => command = Command::ToggleBotStatusMessages,
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -359,6 +371,213 @@ pub async fn process_command(
|
|||||||
);
|
);
|
||||||
return "I am no longer sneaking!".to_string();
|
return "I am no longer sneaking!".to_string();
|
||||||
}
|
}
|
||||||
|
Command::Interact => {
|
||||||
|
if segments.len() < 1 {
|
||||||
|
return "Please give me IDs to interact with!".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut found = false;
|
||||||
|
let mob_locations = state.mob_locations.lock().unwrap().to_owned();
|
||||||
|
for (mob, _) in mob_locations {
|
||||||
|
if mob.id.to_string() == segments[0]
|
||||||
|
|| mob.uuid == segments[0]
|
||||||
|
|| mob.entity_type == segments[0]
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::Interact(
|
||||||
|
game::serverbound_interact_packet::ServerboundInteractPacket {
|
||||||
|
action:
|
||||||
|
game::serverbound_interact_packet::ActionType::Interact {
|
||||||
|
hand: InteractionHand::MainHand,
|
||||||
|
},
|
||||||
|
entity_id: mob.id,
|
||||||
|
using_secondary_action: false,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let player_locations = state.player_locations.lock().unwrap().to_owned();
|
||||||
|
for (player, _) in player_locations {
|
||||||
|
if player.entity_id.to_string() == segments[0]
|
||||||
|
|| player.uuid == segments[0]
|
||||||
|
|| player.username == segments[0]
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::Interact(
|
||||||
|
game::serverbound_interact_packet::ServerboundInteractPacket {
|
||||||
|
action:
|
||||||
|
game::serverbound_interact_packet::ActionType::Interact {
|
||||||
|
hand: InteractionHand::MainHand,
|
||||||
|
},
|
||||||
|
entity_id: player.entity_id,
|
||||||
|
using_secondary_action: false,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
return "Successfully interacted with entity!".to_string();
|
||||||
|
} else {
|
||||||
|
return "Unable to find entity!".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::Attack => {
|
||||||
|
if segments.len() < 1 {
|
||||||
|
return "Please give me IDs to attack!".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut found = false;
|
||||||
|
let mob_locations = state.mob_locations.lock().unwrap().to_owned();
|
||||||
|
for (mob, _) in mob_locations {
|
||||||
|
if mob.id.to_string() == segments[0]
|
||||||
|
|| mob.uuid == segments[0]
|
||||||
|
|| mob.entity_type == segments[0]
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::Interact(
|
||||||
|
game::serverbound_interact_packet::ServerboundInteractPacket {
|
||||||
|
action: game::serverbound_interact_packet::ActionType::Attack,
|
||||||
|
entity_id: mob.id,
|
||||||
|
using_secondary_action: false,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let player_locations = state.player_locations.lock().unwrap().to_owned();
|
||||||
|
for (player, _) in player_locations {
|
||||||
|
if player.entity_id.to_string() == segments[0]
|
||||||
|
|| player.uuid == segments[0]
|
||||||
|
|| player.username == segments[0]
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::Interact(
|
||||||
|
game::serverbound_interact_packet::ServerboundInteractPacket {
|
||||||
|
action: game::serverbound_interact_packet::ActionType::Attack,
|
||||||
|
entity_id: player.entity_id,
|
||||||
|
using_secondary_action: false,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
return "Successfully attacked entity!".to_string();
|
||||||
|
} else {
|
||||||
|
return "Unable to find entity!".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::Walk => {
|
||||||
|
if segments.len() < 2 {
|
||||||
|
return "Please give me a direction (and duration) to walk in!".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
let direction = match segments[0].to_lowercase().as_str() {
|
||||||
|
"forward" => WalkDirection::Forward,
|
||||||
|
"forward_left" => WalkDirection::ForwardLeft,
|
||||||
|
"forward_right" => WalkDirection::ForwardRight,
|
||||||
|
"backward" => WalkDirection::Backward,
|
||||||
|
"backward_left" => WalkDirection::BackwardLeft,
|
||||||
|
"backward_right" => WalkDirection::BackwardRight,
|
||||||
|
"left" => WalkDirection::Left,
|
||||||
|
"right" => WalkDirection::Right,
|
||||||
|
_ => WalkDirection::None,
|
||||||
|
};
|
||||||
|
let duration = match segments[1].parse() {
|
||||||
|
Ok(duration) => duration,
|
||||||
|
Err(error) => return format!("Unable to parse duration: {}", error),
|
||||||
|
};
|
||||||
|
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.send_command_packet(&format!(
|
||||||
|
"msg {} I am now walking {} for {} ms!",
|
||||||
|
executor,
|
||||||
|
segments[0].to_lowercase(),
|
||||||
|
duration,
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
client.walk(direction);
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(duration)).await;
|
||||||
|
client.walk(WalkDirection::None);
|
||||||
|
return "I have finished walking!".to_string();
|
||||||
|
}
|
||||||
|
Command::Sprint => {
|
||||||
|
if segments.len() < 2 {
|
||||||
|
return "Please give me a direction (and duration) to sprint in!".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
let direction = match segments[0].to_lowercase().as_str() {
|
||||||
|
"forward" => SprintDirection::Forward,
|
||||||
|
"forward_left" => SprintDirection::ForwardLeft,
|
||||||
|
"forward_right" => SprintDirection::ForwardRight,
|
||||||
|
_ => return "Please give me a valid direction to sprint in!".to_string(),
|
||||||
|
};
|
||||||
|
let duration = match segments[1].parse() {
|
||||||
|
Ok(duration) => duration,
|
||||||
|
Err(error) => return format!("Unable to parse duration: {}", error),
|
||||||
|
};
|
||||||
|
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.send_command_packet(&format!(
|
||||||
|
"msg {} I am now sprinting {} for {} ms!",
|
||||||
|
executor,
|
||||||
|
segments[0].to_lowercase(),
|
||||||
|
duration,
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
client.sprint(direction);
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(duration)).await;
|
||||||
|
client.walk(WalkDirection::None);
|
||||||
|
return "I have finished sprinting!".to_string();
|
||||||
|
}
|
||||||
|
Command::DropItem => {
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::PlayerAction(
|
||||||
|
game::serverbound_player_action_packet::ServerboundPlayerActionPacket {
|
||||||
|
action: game::serverbound_player_action_packet::Action::DropItem,
|
||||||
|
pos: BlockPos { x: 0, y: 0, z: 0 },
|
||||||
|
direction: Default::default(),
|
||||||
|
sequence: 0,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
return "I have successfully dropped 1 item!".to_string();
|
||||||
|
}
|
||||||
|
Command::DropStack => {
|
||||||
|
log_error(
|
||||||
|
client
|
||||||
|
.write_packet(ServerboundGamePacket::PlayerAction(
|
||||||
|
game::serverbound_player_action_packet::ServerboundPlayerActionPacket {
|
||||||
|
action: game::serverbound_player_action_packet::Action::DropAllItems,
|
||||||
|
pos: BlockPos { x: 0, y: 0, z: 0 },
|
||||||
|
direction: Default::default(),
|
||||||
|
sequence: 0,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.await,
|
||||||
|
);
|
||||||
|
return "I have successfully dropped 1 stack!".to_string();
|
||||||
|
}
|
||||||
Command::ToggleAlertMessages => {
|
Command::ToggleAlertMessages => {
|
||||||
if state.alert_players.lock().unwrap().contains(executor) {
|
if state.alert_players.lock().unwrap().contains(executor) {
|
||||||
let mut players = state.alert_players.lock().unwrap().to_vec();
|
let mut players = state.alert_players.lock().unwrap().to_vec();
|
||||||
|
72
src/main.rs
72
src/main.rs
@ -111,6 +111,7 @@ async fn main() {
|
|||||||
alert_second_counter: Arc::new(Mutex::new(0)),
|
alert_second_counter: Arc::new(Mutex::new(0)),
|
||||||
followed_player: Arc::new(Mutex::new(None)),
|
followed_player: Arc::new(Mutex::new(None)),
|
||||||
player_locations: Arc::new(Mutex::new(HashMap::new())),
|
player_locations: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
mob_locations: Arc::new(Mutex::new(HashMap::new())),
|
||||||
player_timestamps: Arc::new(Mutex::new(HashMap::new())),
|
player_timestamps: Arc::new(Mutex::new(HashMap::new())),
|
||||||
alert_players: Arc::new(Mutex::new(bot_configuration.clone().alert_players)),
|
alert_players: Arc::new(Mutex::new(bot_configuration.clone().alert_players)),
|
||||||
alert_queue: Arc::new(Mutex::new(HashMap::new())),
|
alert_queue: Arc::new(Mutex::new(HashMap::new())),
|
||||||
@ -130,11 +131,18 @@ async fn main() {
|
|||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq, PartialOrd, Debug, Clone)]
|
#[derive(Eq, Hash, PartialEq, PartialOrd, Debug, Clone)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
uuid: u128,
|
uuid: String,
|
||||||
entity_id: u32,
|
entity_id: u32,
|
||||||
username: String,
|
username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq, PartialOrd, Debug, Clone)]
|
||||||
|
pub struct Entity {
|
||||||
|
id: u32,
|
||||||
|
uuid: String,
|
||||||
|
entity_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct PositionTimeData {
|
pub struct PositionTimeData {
|
||||||
position: Vec<i32>,
|
position: Vec<i32>,
|
||||||
@ -165,6 +173,7 @@ pub struct State {
|
|||||||
alert_second_counter: Arc<Mutex<u8>>,
|
alert_second_counter: Arc<Mutex<u8>>,
|
||||||
followed_player: Arc<Mutex<Option<Player>>>,
|
followed_player: Arc<Mutex<Option<Player>>>,
|
||||||
player_locations: Arc<Mutex<HashMap<Player, PositionTimeData>>>,
|
player_locations: Arc<Mutex<HashMap<Player, PositionTimeData>>>,
|
||||||
|
mob_locations: Arc<Mutex<HashMap<Entity, PositionTimeData>>>,
|
||||||
player_timestamps: Arc<Mutex<HashMap<String, PlayerTimeData>>>,
|
player_timestamps: Arc<Mutex<HashMap<String, PlayerTimeData>>>,
|
||||||
alert_players: Arc<Mutex<Vec<String>>>,
|
alert_players: Arc<Mutex<Vec<String>>>,
|
||||||
alert_queue: Arc<Mutex<HashMap<String, Vec<i32>>>>,
|
alert_queue: Arc<Mutex<HashMap<String, Vec<i32>>>>,
|
||||||
@ -311,29 +320,37 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R
|
|||||||
}
|
}
|
||||||
Event::Packet(packet) => match packet.as_ref() {
|
Event::Packet(packet) => match packet.as_ref() {
|
||||||
ClientboundGamePacket::MoveEntityPos(packet) => {
|
ClientboundGamePacket::MoveEntityPos(packet) => {
|
||||||
let entity: (u128, u32, azalea::Vec3) =
|
let world = client.world.read();
|
||||||
match (client.world.read()).entity(packet.entity_id) {
|
let raw_entity = match world.entity(packet.entity_id) {
|
||||||
Some(entity) => (entity.uuid.as_u128(), entity.id, entity.pos().to_owned()),
|
Some(raw_entity) => raw_entity,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
let entity = Entity {
|
||||||
|
id: raw_entity.id,
|
||||||
|
uuid: raw_entity.uuid.as_hyphenated().to_string(),
|
||||||
|
entity_type: format!("{:?}", raw_entity.metadata),
|
||||||
|
};
|
||||||
|
let entity_position = raw_entity.pos();
|
||||||
|
|
||||||
|
let mut is_player = false;
|
||||||
let players = client.players.read().to_owned();
|
let players = client.players.read().to_owned();
|
||||||
for (uuid, player) in players.iter().map(|item| item.to_owned()) {
|
for (uuid, player) in players.iter().map(|item| item.to_owned()) {
|
||||||
if uuid.as_u128() == entity.0 {
|
if uuid.as_hyphenated().to_string() == entity.uuid {
|
||||||
let position = entity.2;
|
is_player = true;
|
||||||
|
|
||||||
let mut player_locations =
|
let mut player_locations =
|
||||||
state.player_locations.lock().unwrap().to_owned();
|
state.player_locations.lock().unwrap().to_owned();
|
||||||
player_locations.insert(
|
player_locations.insert(
|
||||||
Player {
|
Player {
|
||||||
uuid: uuid.as_u128(),
|
uuid: uuid.as_hyphenated().to_string(),
|
||||||
entity_id: entity.1,
|
entity_id: entity.id,
|
||||||
username: player.profile.name.to_owned(),
|
username: player.profile.name.to_owned(),
|
||||||
},
|
},
|
||||||
PositionTimeData {
|
PositionTimeData {
|
||||||
position: vec![
|
position: vec![
|
||||||
position.x as i32,
|
entity_position.x as i32,
|
||||||
position.y as i32,
|
entity_position.y as i32,
|
||||||
position.z as i32,
|
entity_position.z as i32,
|
||||||
],
|
],
|
||||||
time: SystemTime::now()
|
time: SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
@ -347,12 +364,12 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R
|
|||||||
- state.bot_configuration.alert_radius)
|
- state.bot_configuration.alert_radius)
|
||||||
..(state.bot_configuration.alert_location[0]
|
..(state.bot_configuration.alert_location[0]
|
||||||
+ state.bot_configuration.alert_radius))
|
+ state.bot_configuration.alert_radius))
|
||||||
.contains(&(position.x as i32))
|
.contains(&(entity_position.x as i32))
|
||||||
&& ((state.bot_configuration.alert_location[1]
|
&& ((state.bot_configuration.alert_location[1]
|
||||||
- state.bot_configuration.alert_radius)
|
- state.bot_configuration.alert_radius)
|
||||||
..(state.bot_configuration.alert_location[1]
|
..(state.bot_configuration.alert_location[1]
|
||||||
+ state.bot_configuration.alert_radius))
|
+ state.bot_configuration.alert_radius))
|
||||||
.contains(&(position.z as i32))
|
.contains(&(entity_position.z as i32))
|
||||||
{
|
{
|
||||||
if !state
|
if !state
|
||||||
.whitelist
|
.whitelist
|
||||||
@ -363,13 +380,36 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R
|
|||||||
let mut alert_queue = state.alert_queue.lock().unwrap().to_owned();
|
let mut alert_queue = state.alert_queue.lock().unwrap().to_owned();
|
||||||
alert_queue.insert(
|
alert_queue.insert(
|
||||||
player.profile.name.to_owned(),
|
player.profile.name.to_owned(),
|
||||||
vec![position.x as i32, position.y as i32, position.z as i32],
|
vec![
|
||||||
|
entity_position.x as i32,
|
||||||
|
entity_position.y as i32,
|
||||||
|
entity_position.z as i32,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
*state.alert_queue.lock().unwrap() = alert_queue;
|
*state.alert_queue.lock().unwrap() = alert_queue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !is_player {
|
||||||
|
let mut mob_locations = state.mob_locations.lock().unwrap().to_owned();
|
||||||
|
mob_locations.insert(
|
||||||
|
entity,
|
||||||
|
PositionTimeData {
|
||||||
|
position: vec![
|
||||||
|
entity_position.x as i32,
|
||||||
|
entity_position.y as i32,
|
||||||
|
entity_position.z as i32,
|
||||||
|
],
|
||||||
|
time: SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
*state.mob_locations.lock().unwrap() = mob_locations;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ClientboundGamePacket::SetHealth(packet) => {
|
ClientboundGamePacket::SetHealth(packet) => {
|
||||||
*state.bot_status.lock().unwrap() = BotStatus {
|
*state.bot_status.lock().unwrap() = BotStatus {
|
||||||
@ -391,9 +431,9 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R
|
|||||||
"msg {} {}",
|
"msg {} {}",
|
||||||
player,
|
player,
|
||||||
format!(
|
format!(
|
||||||
"Health: {}/20, Food: {}/20, Saturation: {}/20",
|
"Health: {:.1}/20, Food: {}/20, Saturation: {:.1}/20",
|
||||||
packet.health, packet.food, packet.saturation
|
packet.health, packet.food, packet.saturation
|
||||||
)
|
),
|
||||||
))
|
))
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user