diff --git a/src/bot.rs b/src/bot.rs index d727960..5e6b8ea 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -42,6 +42,7 @@ pub enum Command { LeaveBed, Script, Latency, + MobLocations, ToggleBotStatusMessages, ToggleAlertMessages, Unknown, @@ -93,6 +94,7 @@ pub async fn process_command( "leave_bed" => command = Command::LeaveBed, "script" => command = Command::Script, "latency" => command = Command::Latency, + "mob_locations" => command = Command::MobLocations, "toggle_alert_messages" => command = Command::ToggleAlertMessages, "toggle_bot_status_messages" => command = Command::ToggleBotStatusMessages, _ => (), @@ -788,6 +790,45 @@ pub async fn process_command( return format!("{} was not found!", player); } + Command::MobLocations => { + if segments.len() < 1 { + return "Please give me the ID or type of a mob!".to_string(); + } + let mut page = 1; + if segments.len() > 1 { + page = segments[1].parse().unwrap_or(1) + } + if page < 1 { + page = 1 + } + + let mut locations = Vec::new(); + for (entity, position_time_data) in state.mob_locations.lock().unwrap().to_owned() { + if entity.id.to_string() == segments[0] + || entity.uuid == segments[0] + || entity.entity_type == segments[0] + { + locations.push(format!( + "{}: {} {} {}", + entity.entity_type, + position_time_data.position[0], + position_time_data.position[1], + position_time_data.position[2], + )) + } + } + + let mut start_index = (page - 1) * 5; + let mut end_index = page * 5; + while start_index > locations.len() { + start_index -= 1 + } + while end_index > locations.len() { + end_index -= 1 + } + let paged_locations = &locations[start_index..end_index]; + return format!("Locations (page {}): {}", page, paged_locations.join(", ")); + } Command::ToggleAlertMessages => { if state.alert_players.lock().unwrap().contains(executor) { let mut players = state.alert_players.lock().unwrap().to_vec(); diff --git a/src/main.rs b/src/main.rs index ff0f3dd..d88ed6c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -108,7 +108,8 @@ async fn main() { whitelist: Arc::new(Mutex::new(bot_configuration.clone().whitelist)), bot_status: Arc::new(Mutex::new(BotStatus::default())), tick_counter: Arc::new(Mutex::new(0)), - second_counter: Arc::new(Mutex::new(0)), + alert_second_counter: Arc::new(Mutex::new(0)), + cleanup_second_counter: Arc::new(Mutex::new(0)), followed_player: Arc::new(Mutex::new(None)), player_locations: Arc::new(Mutex::new(HashMap::new())), mob_locations: Arc::new(Mutex::new(HashMap::new())), @@ -173,7 +174,8 @@ pub struct State { whitelist: Arc>>, bot_status: Arc>, tick_counter: Arc>, - second_counter: Arc>, + alert_second_counter: Arc>, + cleanup_second_counter: Arc>, followed_player: Arc>>, player_locations: Arc>>, mob_locations: Arc>>, @@ -252,7 +254,8 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R *state.tick_counter.lock().unwrap() += 1; if *state.tick_counter.lock().unwrap() >= 20 { *state.tick_counter.lock().unwrap() = 0; - *state.second_counter.lock().unwrap() += 1; + *state.alert_second_counter.lock().unwrap() += 1; + *state.cleanup_second_counter.lock().unwrap() += 1; let followed_player = state.followed_player.lock().unwrap().to_owned(); if followed_player.is_some() { @@ -270,8 +273,8 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R } } - if *state.second_counter.lock().unwrap() >= 5 { - *state.second_counter.lock().unwrap() = 0; + if *state.alert_second_counter.lock().unwrap() >= 5 { + *state.alert_second_counter.lock().unwrap() = 0; let alert_queue = state.alert_queue.lock().unwrap().to_owned(); for (intruder, position) in alert_queue { @@ -313,6 +316,13 @@ async fn handle(mut client: Client, event: Event, mut state: State) -> anyhow::R } *state.alert_queue.lock().unwrap() = HashMap::new(); } + + if *state.cleanup_second_counter.lock().unwrap() >= 600 { + *state.cleanup_second_counter.lock().unwrap() = 0; + + log_message(Bot, &"Cleaning up mob locations...".to_string()); + *state.mob_locations.lock().unwrap() = HashMap::new(); + } } Event::Packet(packet) => match packet.as_ref() { ClientboundGamePacket::MoveEntityPos(packet) => {