fix(client): handle borrows with async
This commit is contained in:
@@ -7,6 +7,7 @@ use azalea::{
|
||||
use mlua::{Lua, Result, UserDataRef, Value};
|
||||
|
||||
use super::{Client, Container, ContainerRef, ItemStack, Vec3};
|
||||
use crate::unpack;
|
||||
|
||||
pub fn container(_lua: &Lua, client: &Client) -> Result<ContainerRef> {
|
||||
Ok(ContainerRef(client.get_inventory()))
|
||||
@@ -95,9 +96,10 @@ pub async fn open_container_at(
|
||||
client: UserDataRef<Client>,
|
||||
position: Vec3,
|
||||
) -> Result<Option<Container>> {
|
||||
let client = unpack!(client);
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Ok(client
|
||||
.clone()
|
||||
.open_container_at(BlockPos::new(
|
||||
position.x as i32,
|
||||
position.y as i32,
|
||||
|
||||
@@ -6,6 +6,7 @@ use azalea::{
|
||||
use mlua::{Lua, Result, UserDataRef};
|
||||
|
||||
use super::{Client, Vec3};
|
||||
use crate::unpack;
|
||||
|
||||
pub fn attack(_lua: &Lua, client: &Client, entity_id: i32) -> Result<()> {
|
||||
if let Some(entity) = client.entity_id_by_minecraft_id(MinecraftEntityId(entity_id)) {
|
||||
@@ -29,9 +30,10 @@ pub fn has_attack_cooldown(_lua: &Lua, client: &Client) -> Result<bool> {
|
||||
}
|
||||
|
||||
pub async fn mine(_lua: Lua, client: UserDataRef<Client>, position: Vec3) -> Result<()> {
|
||||
let client = unpack!(client);
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
client
|
||||
.clone()
|
||||
.mine(BlockPos::new(
|
||||
position.x as i32,
|
||||
position.y as i32,
|
||||
|
||||
@@ -6,7 +6,7 @@ mod movement;
|
||||
mod state;
|
||||
mod world;
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::Deref;
|
||||
|
||||
use azalea::{Client as AzaleaClient, core::entity_id::MinecraftEntityId};
|
||||
use mlua::{Lua, Result, UserData, UserDataFields, UserDataMethods};
|
||||
@@ -28,12 +28,6 @@ impl Deref for Client {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Client {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.0.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);
|
||||
@@ -121,3 +115,12 @@ fn username(_lua: &Lua, client: &Client) -> Result<String> {
|
||||
fn uuid(_lua: &Lua, client: &Client) -> Result<String> {
|
||||
Ok(client.uuid().to_string())
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unpack {
|
||||
($client:ident) => {{
|
||||
let inner = (**$client).clone();
|
||||
drop($client);
|
||||
inner
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use azalea::{
|
||||
BlockPos, SprintDirection, WalkDirection,
|
||||
BlockPos, Client as AzaleaClient, SprintDirection, WalkDirection,
|
||||
core::{entity_id::MinecraftEntityId, hit_result::HitResult},
|
||||
entity::Position,
|
||||
interact::pick::HitResultComponent,
|
||||
@@ -12,6 +12,7 @@ use azalea::{
|
||||
use mlua::{FromLua, Lua, Result, Table, UserDataRef, Value};
|
||||
|
||||
use super::{Client, Direction, Vec3};
|
||||
use crate::unpack;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AnyGoal(Box<dyn Goal>);
|
||||
@@ -27,7 +28,7 @@ impl Goal for AnyGoal {
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
fn to_goal(lua: &Lua, client: &Client, data: Table, kind: u8) -> Result<AnyGoal> {
|
||||
fn to_goal(lua: &Lua, client: &AzaleaClient, data: Table, kind: u8) -> Result<AnyGoal> {
|
||||
let goal: Box<dyn Goal> = match kind {
|
||||
1 => {
|
||||
let pos = Vec3::from_lua(data.get("position")?, lua)?;
|
||||
@@ -68,6 +69,7 @@ pub fn go_to_reached(_lua: &Lua, client: &Client) -> Result<bool> {
|
||||
}
|
||||
|
||||
pub async fn wait_until_goal_reached(_lua: Lua, client: UserDataRef<Client>, (): ()) -> Result<()> {
|
||||
let client = unpack!(client);
|
||||
client.wait_until_goto_target_reached().await;
|
||||
Ok(())
|
||||
}
|
||||
@@ -77,6 +79,8 @@ pub async fn go_to(
|
||||
client: UserDataRef<Client>,
|
||||
(data, metadata): (Table, Option<Table>),
|
||||
) -> Result<()> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let metadata = metadata.unwrap_or(lua.create_table()?);
|
||||
let options = metadata.get("options").unwrap_or(lua.create_table()?);
|
||||
let goal = to_goal(
|
||||
@@ -85,12 +89,13 @@ pub async fn go_to(
|
||||
data,
|
||||
metadata.get("type").unwrap_or_default(),
|
||||
)?;
|
||||
if options.get("without_mining").unwrap_or_default() {
|
||||
client.start_goto_with_opts(goal, PathfinderOpts::new().allow_mining(false));
|
||||
client.wait_until_goto_target_reached().await;
|
||||
} else {
|
||||
client.goto(goal).await;
|
||||
}
|
||||
client
|
||||
.goto_with_opts(
|
||||
goal,
|
||||
PathfinderOpts::new().allow_mining(options.get("without_mining").unwrap_or_default()),
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -99,6 +104,8 @@ pub async fn start_go_to(
|
||||
client: UserDataRef<Client>,
|
||||
(data, metadata): (Table, Option<Table>),
|
||||
) -> Result<()> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let metadata = metadata.unwrap_or(lua.create_table()?);
|
||||
let options = metadata.get("options").unwrap_or(lua.create_table()?);
|
||||
let goal = to_goal(
|
||||
|
||||
@@ -6,6 +6,7 @@ use azalea_hax::AntiKnockback;
|
||||
use mlua::{Error, Lua, Result, Table, UserDataRef};
|
||||
|
||||
use super::Client;
|
||||
use crate::unpack;
|
||||
|
||||
pub fn air_supply(_lua: &Lua, client: &Client) -> Result<i32> {
|
||||
Ok(client.component::<AirSupply>().0)
|
||||
@@ -37,6 +38,8 @@ pub async fn set_client_information(
|
||||
client: UserDataRef<Client>,
|
||||
info: Table,
|
||||
) -> Result<()> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let get_bool = |table: &Table, name| table.get(name).unwrap_or(true);
|
||||
client.set_client_information(ClientInformation {
|
||||
allows_listing: info.get("allows_listing")?,
|
||||
|
||||
@@ -10,7 +10,7 @@ use azalea::{
|
||||
use mlua::{Function, Lua, Result, Table, UserDataRef};
|
||||
|
||||
use super::{Client, Direction, Vec3};
|
||||
use crate::lua::client::MinecraftEntityId;
|
||||
use crate::{lua::client::MinecraftEntityId, unpack};
|
||||
|
||||
pub fn blocks(
|
||||
_lua: &Lua,
|
||||
@@ -39,6 +39,8 @@ pub fn blocks(
|
||||
}
|
||||
|
||||
pub async fn all_entities(lua: Lua, client: UserDataRef<Client>, (): ()) -> Result<Vec<Table>> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let mut matched = Vec::with_capacity(256);
|
||||
for (position, custom_name, kind, uuid, direction, id, owner_uuid, pose) in
|
||||
get_entities!(client)
|
||||
@@ -65,6 +67,8 @@ pub async fn entities(
|
||||
client: UserDataRef<Client>,
|
||||
filter_fn: Function,
|
||||
) -> Result<Vec<Table>> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let mut matched = Vec::new();
|
||||
for (position, custom_name, kind, uuid, direction, id, owner_uuid, pose) in
|
||||
get_entities!(client)
|
||||
@@ -89,6 +93,8 @@ pub async fn entities(
|
||||
}
|
||||
|
||||
pub async fn all_players(lua: Lua, client: UserDataRef<Client>, (): ()) -> Result<Vec<Table>> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let mut matched = Vec::new();
|
||||
for (id, uuid, kind, position, direction, pose) in get_players!(client) {
|
||||
let table = lua.create_table()?;
|
||||
@@ -108,6 +114,8 @@ pub async fn players(
|
||||
client: UserDataRef<Client>,
|
||||
filter_fn: Function,
|
||||
) -> Result<Vec<Table>> {
|
||||
let client = unpack!(client);
|
||||
|
||||
let mut matched = Vec::new();
|
||||
for (id, uuid, kind, position, direction, pose) in get_players!(client) {
|
||||
let table = lua.create_table()?;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#[macro_export]
|
||||
macro_rules! get_entities {
|
||||
($client:ident) => {{
|
||||
let mut ecs = $client.ecs.write();
|
||||
ecs.query::<(
|
||||
let ecs = $client.ecs.read();
|
||||
if let Some(mut query) = ecs.try_query::<(
|
||||
&AzaleaPosition,
|
||||
&CustomName,
|
||||
&EntityKindComponent,
|
||||
@@ -11,31 +11,35 @@ macro_rules! get_entities {
|
||||
&MinecraftEntityId,
|
||||
Option<&Owneruuid>,
|
||||
&Pose,
|
||||
)>()
|
||||
.iter(&ecs)
|
||||
.map(
|
||||
|(position, custom_name, kind, uuid, direction, id, owner_uuid, pose)| {
|
||||
(
|
||||
Vec3::from(*position),
|
||||
custom_name.as_ref().map(ToString::to_string),
|
||||
kind.to_string(),
|
||||
uuid.to_string(),
|
||||
Direction::from(direction),
|
||||
id.0,
|
||||
owner_uuid.map(ToOwned::to_owned),
|
||||
*pose as u8,
|
||||
)>() {
|
||||
query
|
||||
.iter(&ecs)
|
||||
.map(
|
||||
|(position, custom_name, kind, uuid, direction, id, owner_uuid, pose)| {
|
||||
(
|
||||
Vec3::from(*position),
|
||||
custom_name.as_ref().map(ToString::to_string),
|
||||
kind.to_string(),
|
||||
uuid.to_string(),
|
||||
Direction::from(direction),
|
||||
id.0,
|
||||
owner_uuid.map(ToOwned::to_owned),
|
||||
*pose as u8,
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! get_players {
|
||||
($client:ident) => {{
|
||||
let mut ecs = $client.ecs.write();
|
||||
ecs.query_filtered::<(
|
||||
let ecs = $client.ecs.read();
|
||||
if let Some(mut query) = ecs.try_query_filtered::<(
|
||||
&MinecraftEntityId,
|
||||
&EntityUuid,
|
||||
&EntityKindComponent,
|
||||
@@ -43,17 +47,22 @@ macro_rules! get_players {
|
||||
&LookDirection,
|
||||
&Pose,
|
||||
), (With<Player>, Without<Dead>)>()
|
||||
.iter(&ecs)
|
||||
.map(|(id, uuid, kind, position, direction, pose)| {
|
||||
(
|
||||
id.0,
|
||||
uuid.to_string(),
|
||||
kind.to_string(),
|
||||
Vec3::from(*position),
|
||||
Direction::from(direction),
|
||||
*pose as u8,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
query
|
||||
.iter(&ecs)
|
||||
.map(|(id, uuid, kind, position, direction, pose)| {
|
||||
(
|
||||
id.0,
|
||||
uuid.to_string(),
|
||||
kind.to_string(),
|
||||
Vec3::from(*position),
|
||||
Direction::from(direction),
|
||||
*pose as u8,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user