From 8547ea04ab3fd5be452d6f06faa41fcfc4b4e2dd Mon Sep 17 00:00:00 2001 From: ErrorNoInternet <errornointernet@envs.net> Date: Sun, 16 Feb 2025 22:41:28 -0500 Subject: [PATCH] refactor(client): move fields into modules --- src/scripting/client/interaction.rs | 60 +++++------ src/scripting/client/mod.rs | 157 ++++++---------------------- src/scripting/client/movement.rs | 89 +++++++++++++++- src/scripting/client/state.rs | 27 ++++- 4 files changed, 172 insertions(+), 161 deletions(-) diff --git a/src/scripting/client/interaction.rs b/src/scripting/client/interaction.rs index 7ce34d9..a626340 100644 --- a/src/scripting/client/interaction.rs +++ b/src/scripting/client/interaction.rs @@ -2,36 +2,6 @@ use super::{Client, Vec3}; use azalea::{BlockPos, BotClientExt, world::MinecraftEntityId}; use mlua::{Lua, Result, UserDataRefMut}; -pub async fn mine(_lua: Lua, mut client: UserDataRefMut<Client>, position: Vec3) -> Result<()> { - #[allow(clippy::cast_possible_truncation)] - client - .inner - .as_mut() - .unwrap() - .mine(BlockPos::new( - position.x as i32, - position.y as i32, - position.z as i32, - )) - .await; - Ok(()) -} - -pub fn start_mining(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> { - #[allow(clippy::cast_possible_truncation)] - client.inner.as_mut().unwrap().start_mining(BlockPos::new( - position.x as i32, - position.y as i32, - position.z as i32, - )); - Ok(()) -} - -pub fn set_mining(_lua: &Lua, client: &Client, mining: bool) -> Result<()> { - client.inner.as_ref().unwrap().left_click_mine(mining); - Ok(()) -} - pub fn attack(_lua: &Lua, client: &mut Client, entity_id: u32) -> Result<()> { client .inner @@ -50,3 +20,33 @@ pub fn block_interact(_lua: &Lua, client: &mut Client, position: Vec3) -> Result )); Ok(()) } + +pub async fn mine(_lua: Lua, mut client: UserDataRefMut<Client>, position: Vec3) -> Result<()> { + #[allow(clippy::cast_possible_truncation)] + client + .inner + .as_mut() + .unwrap() + .mine(BlockPos::new( + position.x as i32, + position.y as i32, + position.z as i32, + )) + .await; + Ok(()) +} + +pub fn set_mining(_lua: &Lua, client: &Client, mining: bool) -> Result<()> { + client.inner.as_ref().unwrap().left_click_mine(mining); + Ok(()) +} + +pub fn start_mining(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> { + #[allow(clippy::cast_possible_truncation)] + client.inner.as_mut().unwrap().start_mining(BlockPos::new( + position.x as i32, + position.y as i32, + position.z as i32, + )); + Ok(()) +} diff --git a/src/scripting/client/mod.rs b/src/scripting/client/mod.rs index 94b54d9..f52c09d 100644 --- a/src/scripting/client/mod.rs +++ b/src/scripting/client/mod.rs @@ -7,13 +7,8 @@ use super::{ block::Block, direction::Direction, entity::Entity, fluid_state::FluidState, hunger::Hunger, vec3::Vec3, }; -use azalea::{ - Client as AzaleaClient, - entity::metadata::{AirSupply, Score}, - interact::HitResultComponent, - pathfinder::{ExecutingPath, Pathfinder}, -}; -use mlua::{Lua, Result, UserData, UserDataFields, UserDataMethods}; +use azalea::Client as AzaleaClient; +use mlua::{Lua, Result, Table, UserData, UserDataFields, UserDataMethods}; pub struct Client { pub inner: Option<AzaleaClient>, @@ -21,123 +16,17 @@ pub struct Client { impl UserData for Client { fn add_fields<F: UserDataFields<Self>>(f: &mut F) { - f.add_field_method_get("air_supply", |_, this| { - Ok(this.inner.as_ref().unwrap().component::<AirSupply>().0) - }); - - f.add_field_method_get("direction", |_, this| { - let d = this.inner.as_ref().unwrap().direction(); - Ok(Direction { x: d.0, y: d.1 }) - }); - - f.add_field_method_get("eye_position", |_, this| { - let p = this.inner.as_ref().unwrap().eye_position(); - Ok(Vec3 { - x: p.x, - y: p.y, - z: p.z, - }) - }); - - f.add_field_method_get("health", |_, this| { - Ok(this.inner.as_ref().unwrap().health()) - }); - - f.add_field_method_get("hunger", |_, this| { - let h = this.inner.as_ref().unwrap().hunger(); - Ok(Hunger { - food: h.food, - saturation: h.saturation, - }) - }); - - f.add_field_method_get("looking_at", |lua, this| { - let hr = this - .inner - .as_ref() - .unwrap() - .component::<HitResultComponent>(); - Ok(if hr.miss { - None - } else { - let result = lua.create_table()?; - result.set( - "position", - Vec3 { - x: f64::from(hr.block_pos.x), - y: f64::from(hr.block_pos.y), - z: f64::from(hr.block_pos.z), - }, - )?; - result.set("inside", hr.inside)?; - result.set("world_border", hr.world_border)?; - Some(result) - }) - }); - - f.add_field_method_get("pathfinder", |lua, this| { - let client = this.inner.as_ref().unwrap(); - let pathfinder = lua.create_table()?; - pathfinder.set( - "is_calculating", - client.component::<Pathfinder>().is_calculating, - )?; - pathfinder.set( - "is_executing", - if let Some(p) = client.get_component::<ExecutingPath>() { - pathfinder.set( - "last_reached_node", - Vec3 { - x: f64::from(p.last_reached_node.x), - y: f64::from(p.last_reached_node.y), - z: f64::from(p.last_reached_node.z), - }, - )?; - pathfinder.set( - "last_node_reach_elapsed", - p.last_node_reached_at.elapsed().as_millis(), - )?; - pathfinder.set("is_path_partial", p.is_path_partial)?; - true - } else { - false - }, - )?; - Ok(pathfinder) - }); - - f.add_field_method_get("position", |_, this| { - let p = this.inner.as_ref().unwrap().position(); - Ok(Vec3 { - x: p.x, - y: p.y, - z: p.z, - }) - }); - - f.add_field_method_get("score", |_, this| { - Ok(this.inner.as_ref().unwrap().component::<Score>().0) - }); - - f.add_field_method_get("tab_list", |lua, this| { - let tab_list = lua.create_table()?; - for (uuid, player_info) in this.inner.as_ref().unwrap().tab_list() { - let player = lua.create_table()?; - player.set("gamemode", player_info.gamemode.name())?; - player.set("latency", player_info.latency)?; - player.set("name", player_info.profile.name)?; - player.set( - "display_name", - player_info.display_name.map(|n| n.to_string()), - )?; - tab_list.set(uuid.to_string(), player)?; - } - Ok(tab_list) - }); - - f.add_field_method_get("uuid", |_, this| { - Ok(this.inner.as_ref().unwrap().uuid().to_string()) - }); + f.add_field_method_get("air_supply", state::air_supply); + f.add_field_method_get("direction", movement::direction); + f.add_field_method_get("eye_position", movement::eye_position); + f.add_field_method_get("health", state::health); + f.add_field_method_get("hunger", state::hunger); + f.add_field_method_get("looking_at", movement::looking_at); + f.add_field_method_get("pathfinder", movement::pathfinder); + f.add_field_method_get("position", movement::position); + f.add_field_method_get("score", state::score); + f.add_field_method_get("tab_list", tab_list); + f.add_field_method_get("uuid", uuid); } fn add_methods<M: UserDataMethods<Self>>(m: &mut M) { @@ -164,6 +53,26 @@ impl UserData for Client { } } +fn tab_list(lua: &Lua, client: &Client) -> Result<Table> { + let tab_list = lua.create_table()?; + for (uuid, player_info) in client.inner.as_ref().unwrap().tab_list() { + let player = lua.create_table()?; + player.set("gamemode", player_info.gamemode.name())?; + player.set("latency", player_info.latency)?; + player.set("name", player_info.profile.name)?; + player.set( + "display_name", + player_info.display_name.map(|n| n.to_string()), + )?; + tab_list.set(uuid.to_string(), player)?; + } + Ok(tab_list) +} + +fn uuid(_lua: &Lua, client: &Client) -> Result<String> { + Ok(client.inner.as_ref().unwrap().uuid().to_string()) +} + fn chat(_lua: &Lua, client: &Client, message: String) -> Result<()> { client.inner.as_ref().unwrap().chat(&message); Ok(()) diff --git a/src/scripting/client/movement.rs b/src/scripting/client/movement.rs index f1b40f1..6025add 100644 --- a/src/scripting/client/movement.rs +++ b/src/scripting/client/movement.rs @@ -1,16 +1,26 @@ -use super::{Client, Vec3}; +use super::{Client, Direction, Vec3}; use azalea::{ BlockPos, BotClientExt, Client as AzaleaClient, SprintDirection, WalkDirection, + interact::HitResultComponent, pathfinder::{ - PathfinderClientExt, + ExecutingPath, Pathfinder, PathfinderClientExt, goals::{BlockPosGoal, Goal, RadiusGoal, ReachBlockPosGoal, XZGoal, YGoal}, }, }; use mlua::{FromLua, Lua, Result, Table, Value}; -pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> { - client.inner.as_ref().unwrap().stop_pathfinding(); - Ok(()) +pub fn direction(_lua: &Lua, client: &Client) -> Result<Direction> { + let d = client.inner.as_ref().unwrap().direction(); + Ok(Direction { x: d.0, y: d.1 }) +} + +pub fn eye_position(_lua: &Lua, client: &Client) -> Result<Vec3> { + let p = client.inner.as_ref().unwrap().eye_position(); + Ok(Vec3 { + x: p.x, + y: p.y, + z: p.z, + }) } pub fn goto( @@ -102,6 +112,30 @@ pub fn jump(_lua: &Lua, client: &mut Client, _: ()) -> Result<()> { Ok(()) } +pub fn looking_at(lua: &Lua, client: &Client) -> Result<Option<Table>> { + let hr = client + .inner + .as_ref() + .unwrap() + .component::<HitResultComponent>(); + Ok(if hr.miss { + None + } else { + let result = lua.create_table()?; + result.set( + "position", + Vec3 { + x: f64::from(hr.block_pos.x), + y: f64::from(hr.block_pos.y), + z: f64::from(hr.block_pos.z), + }, + )?; + result.set("inside", hr.inside)?; + result.set("world_border", hr.world_border)?; + Some(result) + }) +} + pub fn look_at(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> { client .inner @@ -111,6 +145,46 @@ pub fn look_at(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> { Ok(()) } +pub fn pathfinder(lua: &Lua, client: &Client) -> Result<Table> { + let client = client.inner.as_ref().unwrap(); + let pathfinder = lua.create_table()?; + pathfinder.set( + "is_calculating", + client.component::<Pathfinder>().is_calculating, + )?; + pathfinder.set( + "is_executing", + if let Some(p) = client.get_component::<ExecutingPath>() { + pathfinder.set( + "last_reached_node", + Vec3 { + x: f64::from(p.last_reached_node.x), + y: f64::from(p.last_reached_node.y), + z: f64::from(p.last_reached_node.z), + }, + )?; + pathfinder.set( + "last_node_reach_elapsed", + p.last_node_reached_at.elapsed().as_millis(), + )?; + pathfinder.set("is_path_partial", p.is_path_partial)?; + true + } else { + false + }, + )?; + Ok(pathfinder) +} + +pub fn position(_lua: &Lua, client: &Client) -> Result<Vec3> { + let p = client.inner.as_ref().unwrap().position(); + Ok(Vec3 { + x: p.x, + y: p.y, + z: p.z, + }) +} + pub fn set_direction(_lua: &Lua, client: &mut Client, direction: (f32, f32)) -> Result<()> { client .inner @@ -134,6 +208,11 @@ pub fn sprint(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> { Ok(()) } +pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> { + client.inner.as_ref().unwrap().stop_pathfinding(); + Ok(()) +} + pub fn walk(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> { client.inner.as_mut().unwrap().walk(match direction { 1 => WalkDirection::Forward, diff --git a/src/scripting/client/state.rs b/src/scripting/client/state.rs index cf7af8a..1f7a34a 100644 --- a/src/scripting/client/state.rs +++ b/src/scripting/client/state.rs @@ -1,7 +1,30 @@ -use super::Client; -use azalea::ClientInformation; +use super::{Client, Hunger}; +use azalea::{ + ClientInformation, + entity::metadata::{AirSupply, Score}, +}; use mlua::{Lua, Result, Table, UserDataRef}; +pub fn air_supply(_lua: &Lua, client: &Client) -> Result<i32> { + Ok(client.inner.as_ref().unwrap().component::<AirSupply>().0) +} + +pub fn health(_lua: &Lua, client: &Client) -> Result<f32> { + Ok(client.inner.as_ref().unwrap().health()) +} + +pub fn hunger(_lua: &Lua, client: &Client) -> Result<Hunger> { + let h = client.inner.as_ref().unwrap().hunger(); + Ok(Hunger { + food: h.food, + saturation: h.saturation, + }) +} + +pub fn score(_lua: &Lua, client: &Client) -> Result<i32> { + Ok(client.inner.as_ref().unwrap().component::<Score>().0) +} + pub async fn set_client_information( _lua: Lua, client: UserDataRef<Client>,