refactor(client): simplify usage with deref

This commit is contained in:
Ryan 2025-02-18 21:34:57 -05:00
parent 93a2dda8c6
commit 75d4a9c183
Signed by: ErrorNoInternet
GPG Key ID: 2486BFB7B1E6A4A3
7 changed files with 68 additions and 108 deletions

View File

@ -59,7 +59,7 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
commands.register(
literal("eval").then(argument("code", string()).executes(|ctx: &Ctx| {
let source = ctx.source.clone();
let code = get_string(ctx, "code").unwrap();
let code = get_string(ctx, "code").expect("argument should exist");
tokio::spawn(async move {
let source = source.lock().await;
source.reply(&format!("{:?}", eval(&source.state.lua, &code).await));
@ -71,7 +71,7 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
commands.register(
literal("exec").then(argument("code", string()).executes(|ctx: &Ctx| {
let source = ctx.source.clone();
let code = get_string(ctx, "code").unwrap();
let code = get_string(ctx, "code").expect("argument should exist");
tokio::spawn(async move {
let source = source.lock().await;
source.reply(&format!("{:?}", exec(&source.state.lua, &code).await));

View File

@ -8,31 +8,18 @@ use mlua::{Lua, Result, UserDataRef};
pub fn container(_lua: &Lua, client: &Client) -> Result<Option<ContainerRef>> {
Ok(client
.inner
.as_ref()
.unwrap()
.get_open_container()
.map(|c| ContainerRef { inner: c }))
}
pub fn held_item(_lua: &Lua, client: &Client) -> Result<ItemStack> {
Ok(ItemStack {
inner: client
.inner
.as_ref()
.unwrap()
.component::<Inventory>()
.held_item(),
inner: client.component::<Inventory>().held_item(),
})
}
pub fn held_slot(_lua: &Lua, client: &Client) -> Result<u8> {
Ok(client
.inner
.as_ref()
.unwrap()
.component::<Inventory>()
.selected_hotbar_slot)
Ok(client.component::<Inventory>().selected_hotbar_slot)
}
pub async fn open_container_at(
@ -42,9 +29,7 @@ pub async fn open_container_at(
) -> Result<Option<Container>> {
#[allow(clippy::cast_possible_truncation)]
Ok(client
.inner
.clone()
.unwrap()
.open_container_at(BlockPos::new(
position.x as i32,
position.y as i32,
@ -55,12 +40,7 @@ pub async fn open_container_at(
}
pub fn open_inventory(_lua: &Lua, client: &mut Client, _: ()) -> Result<Option<Container>> {
Ok(client
.inner
.as_mut()
.unwrap()
.open_inventory()
.map(|c| Container { inner: c }))
Ok(client.open_inventory().map(|c| Container { inner: c }))
}
pub fn set_held_slot(_lua: &Lua, client: &Client, slot: u8) -> Result<()> {
@ -68,7 +48,6 @@ pub fn set_held_slot(_lua: &Lua, client: &Client, slot: u8) -> Result<()> {
return Ok(());
}
let client = client.inner.as_ref().unwrap();
{
let mut ecs = client.ecs.lock();
let mut inventory = client.query::<&mut Inventory>(&mut ecs);

View File

@ -3,17 +3,13 @@ use azalea::{BlockPos, BotClientExt, world::MinecraftEntityId};
use mlua::{Lua, Result, UserDataRef};
pub fn attack(_lua: &Lua, client: &mut Client, entity_id: u32) -> Result<()> {
client
.inner
.as_mut()
.unwrap()
.attack(MinecraftEntityId(entity_id));
client.attack(MinecraftEntityId(entity_id));
Ok(())
}
pub fn block_interact(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> {
#[allow(clippy::cast_possible_truncation)]
client.inner.as_mut().unwrap().block_interact(BlockPos::new(
client.block_interact(BlockPos::new(
position.x as i32,
position.y as i32,
position.z as i32,
@ -22,15 +18,13 @@ pub fn block_interact(_lua: &Lua, client: &mut Client, position: Vec3) -> Result
}
pub fn has_attack_cooldown(_lua: &Lua, client: &Client) -> Result<bool> {
Ok(client.inner.as_ref().unwrap().has_attack_cooldown())
Ok(client.has_attack_cooldown())
}
pub async fn mine(_lua: Lua, client: UserDataRef<Client>, position: Vec3) -> Result<()> {
#[allow(clippy::cast_possible_truncation)]
client
.inner
.clone()
.unwrap()
.mine(BlockPos::new(
position.x as i32,
position.y as i32,
@ -41,13 +35,13 @@ pub async fn mine(_lua: Lua, client: UserDataRef<Client>, position: Vec3) -> Res
}
pub fn set_mining(_lua: &Lua, client: &Client, mining: bool) -> Result<()> {
client.inner.as_ref().unwrap().left_click_mine(mining);
client.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(
client.start_mining(BlockPos::new(
position.x as i32,
position.y as i32,
position.z as i32,

View File

@ -5,18 +5,36 @@ mod state;
mod world;
use super::{
container::item_stack::ItemStack,
container::{Container, ContainerRef},
container::{Container, ContainerRef, item_stack::ItemStack},
direction::Direction,
vec3::Vec3,
};
use azalea::Client as AzaleaClient;
use mlua::{Lua, Result, Table, UserData, UserDataFields, UserDataMethods};
use std::ops::{Deref, DerefMut};
pub struct Client {
pub inner: Option<AzaleaClient>,
}
impl Deref for Client {
type Target = AzaleaClient;
fn deref(&self) -> &Self::Target {
self.inner
.as_ref()
.expect("should have received init event")
}
}
impl DerefMut for Client {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner
.as_mut()
.expect("should have received init event")
}
}
impl UserData for Client {
fn add_fields<F: UserDataFields<Self>>(f: &mut F) {
f.add_field_method_get("air_supply", state::air_supply);
@ -65,18 +83,18 @@ impl UserData for Client {
}
fn chat(_lua: &Lua, client: &Client, message: String) -> Result<()> {
client.inner.as_ref().unwrap().chat(&message);
client.chat(&message);
Ok(())
}
fn disconnect(_lua: &Lua, client: &Client, _: ()) -> Result<()> {
client.inner.as_ref().unwrap().disconnect();
client.disconnect();
Ok(())
}
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() {
for (uuid, player_info) in client.tab_list() {
let player = lua.create_table()?;
player.set("gamemode", player_info.gamemode.name())?;
player.set("latency", player_info.latency)?;
@ -91,5 +109,5 @@ fn tab_list(lua: &Lua, client: &Client) -> Result<Table> {
}
fn uuid(_lua: &Lua, client: &Client) -> Result<String> {
Ok(client.inner.as_ref().unwrap().uuid().to_string())
Ok(client.uuid().to_string())
}

View File

@ -1,6 +1,6 @@
use super::{Client, Direction, Vec3};
use azalea::{
BlockPos, BotClientExt, Client as AzaleaClient, SprintDirection, WalkDirection,
BlockPos, BotClientExt, SprintDirection, WalkDirection,
interact::HitResultComponent,
pathfinder::{
ExecutingPath, GotoEvent, Pathfinder, PathfinderClientExt,
@ -10,12 +10,12 @@ use azalea::{
use mlua::{FromLua, Lua, Result, Table, UserDataRef, Value};
pub fn direction(_lua: &Lua, client: &Client) -> Result<Direction> {
let d = client.inner.as_ref().unwrap().direction();
let d = client.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();
let p = client.eye_position();
Ok(Vec3 {
x: p.x,
y: p.y,
@ -28,7 +28,7 @@ pub async fn goto(
client: UserDataRef<Client>,
(data, metadata): (Value, Option<Table>),
) -> Result<()> {
fn g(client: &AzaleaClient, without_mining: bool, goal: impl Goal + Send + Sync + 'static) {
fn g(client: &Client, without_mining: bool, goal: impl Goal + Send + Sync + 'static) {
if without_mining {
client.goto_without_mining(goal);
} else {
@ -41,7 +41,6 @@ pub async fn goto(
to: "Table".to_string(),
message: None,
};
let client = client.inner.as_ref().unwrap();
let (goal_type, without_mining) = metadata
.map(|t| {
(
@ -57,7 +56,7 @@ pub async fn goto(
let t = data.as_table().ok_or(error)?;
let p = Vec3::from_lua(t.get("position")?, &lua)?;
g(
client,
&client,
without_mining,
RadiusGoal {
pos: azalea::Vec3::new(p.x, p.y, p.z),
@ -68,7 +67,7 @@ pub async fn goto(
2 => {
let p = Vec3::from_lua(data, &lua)?;
g(
client,
&client,
without_mining,
ReachBlockPosGoal {
pos: BlockPos::new(p.x as i32, p.y as i32, p.z as i32),
@ -79,7 +78,7 @@ pub async fn goto(
3 => {
let t = data.as_table().ok_or(error)?;
g(
client,
&client,
without_mining,
XZGoal {
x: t.get("x")?,
@ -88,7 +87,7 @@ pub async fn goto(
);
}
4 => g(
client,
&client,
without_mining,
YGoal {
y: data.as_integer().ok_or(error)?,
@ -97,7 +96,7 @@ pub async fn goto(
_ => {
let p = Vec3::from_lua(data, &lua)?;
g(
client,
&client,
without_mining,
BlockPosGoal(BlockPos::new(p.x as i32, p.y as i32, p.z as i32)),
);
@ -114,16 +113,12 @@ pub async fn goto(
}
pub fn jump(_lua: &Lua, client: &mut Client, _: ()) -> Result<()> {
client.inner.as_mut().unwrap().jump();
client.jump();
Ok(())
}
pub fn looking_at(lua: &Lua, client: &Client) -> Result<Option<Table>> {
let hr = client
.inner
.as_ref()
.unwrap()
.component::<HitResultComponent>();
let hr = client.component::<HitResultComponent>();
Ok(if hr.miss {
None
} else {
@ -143,16 +138,11 @@ pub fn looking_at(lua: &Lua, client: &Client) -> Result<Option<Table>> {
}
pub fn look_at(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> {
client
.inner
.as_mut()
.unwrap()
.look_at(azalea::Vec3::new(position.x, position.y, position.z));
client.look_at(azalea::Vec3::new(position.x, position.y, position.z));
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",
@ -183,7 +173,7 @@ pub fn pathfinder(lua: &Lua, client: &Client) -> Result<Table> {
}
pub fn position(_lua: &Lua, client: &Client) -> Result<Vec3> {
let p = client.inner.as_ref().unwrap().position();
let p = client.position();
Ok(Vec3 {
x: p.x,
y: p.y,
@ -192,21 +182,17 @@ pub fn position(_lua: &Lua, client: &Client) -> Result<Vec3> {
}
pub fn set_direction(_lua: &Lua, client: &mut Client, direction: (f32, f32)) -> Result<()> {
client
.inner
.as_mut()
.unwrap()
.set_direction(direction.0, direction.1);
client.set_direction(direction.0, direction.1);
Ok(())
}
pub fn set_jumping(_lua: &Lua, client: &mut Client, jumping: bool) -> Result<()> {
client.inner.as_mut().unwrap().set_jumping(jumping);
client.set_jumping(jumping);
Ok(())
}
pub fn sprint(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> {
client.inner.as_mut().unwrap().sprint(match direction {
client.sprint(match direction {
5 => SprintDirection::ForwardRight,
6 => SprintDirection::ForwardLeft,
_ => SprintDirection::Forward,
@ -215,12 +201,12 @@ pub fn sprint(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> {
}
pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> {
client.inner.as_ref().unwrap().stop_pathfinding();
client.stop_pathfinding();
Ok(())
}
pub fn walk(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> {
client.inner.as_mut().unwrap().walk(match direction {
client.walk(match direction {
1 => WalkDirection::Forward,
2 => WalkDirection::Backward,
3 => WalkDirection::Left,

View File

@ -3,18 +3,19 @@ use azalea::{
ClientInformation,
entity::metadata::{AirSupply, Score},
};
use log::error;
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)
Ok(client.component::<AirSupply>().0)
}
pub fn health(_lua: &Lua, client: &Client) -> Result<f32> {
Ok(client.inner.as_ref().unwrap().health())
Ok(client.health())
}
pub fn hunger(lua: &Lua, client: &Client) -> Result<Table> {
let h = client.inner.as_ref().unwrap().hunger();
let h = client.hunger();
let hunger = lua.create_table()?;
hunger.set("food", h.food)?;
@ -23,7 +24,7 @@ pub fn hunger(lua: &Lua, client: &Client) -> Result<Table> {
}
pub fn score(_lua: &Lua, client: &Client) -> Result<i32> {
Ok(client.inner.as_ref().unwrap().component::<Score>().0)
Ok(client.component::<Score>().0)
}
pub async fn set_client_information(
@ -31,15 +32,14 @@ pub async fn set_client_information(
client: UserDataRef<Client>,
client_information: Table,
) -> Result<()> {
client
.inner
.as_ref()
.unwrap()
if let Err(error) = client
.set_client_information(ClientInformation {
view_distance: client_information.get("view_distance")?,
..ClientInformation::default()
})
.await
.unwrap();
{
error!("failed to set client client information: {error:?}");
}
Ok(())
}

View File

@ -10,11 +10,7 @@ use azalea::{
use mlua::{Function, Lua, Result, Table};
pub fn best_tool_for_block(lua: &Lua, client: &Client, block_state: u16) -> Result<Table> {
let tr = client
.inner
.as_ref()
.unwrap()
.best_tool_in_hotbar_for_block(BlockState { id: block_state });
let tr = client.best_tool_in_hotbar_for_block(BlockState { id: block_state });
let tool_result = lua.create_table()?;
tool_result.set("index", tr.index)?;
@ -29,9 +25,6 @@ pub fn find_blocks(
) -> Result<Vec<Vec3>> {
#[allow(clippy::cast_possible_truncation)]
Ok(client
.inner
.as_ref()
.unwrap()
.world()
.read()
.find_blocks(
@ -55,7 +48,7 @@ pub fn find_blocks(
pub fn find_entities(lua: &Lua, client: &Client, filter_fn: Function) -> Result<Vec<Table>> {
let mut matched = Vec::new();
let mut ecs = client.inner.as_ref().unwrap().ecs.lock();
let mut ecs = client.ecs.lock();
let mut query = ecs.query_filtered::<(
&MinecraftEntityId,
&EntityUuid,
@ -90,9 +83,6 @@ pub fn find_entities(lua: &Lua, client: &Client, filter_fn: Function) -> Result<
pub fn get_block_state(_lua: &Lua, client: &Client, position: Vec3) -> Result<Option<u16>> {
#[allow(clippy::cast_possible_truncation)]
Ok(client
.inner
.as_ref()
.unwrap()
.world()
.read()
.get_block_state(&BlockPos::new(
@ -106,18 +96,11 @@ pub fn get_block_state(_lua: &Lua, client: &Client, position: Vec3) -> Result<Op
pub fn get_fluid_state(lua: &Lua, client: &Client, position: Vec3) -> Result<Option<Table>> {
#[allow(clippy::cast_possible_truncation)]
Ok(
if let Some(fs) = client
.inner
.as_ref()
.unwrap()
.world()
.read()
.get_fluid_state(&BlockPos::new(
if let Some(fs) = client.world().read().get_fluid_state(&BlockPos::new(
position.x as i32,
position.y as i32,
position.z as i32,
))
{
)) {
let fluid_state = lua.create_table()?;
fluid_state.set("kind", fs.kind as u8)?;
fluid_state.set("amount", fs.amount)?;