refactor: clean up and restructure
This commit is contained in:
@@ -1,109 +0,0 @@
|
||||
use super::position::{from_table, to_table};
|
||||
use azalea::{
|
||||
BlockPos, Client as AzaleaClient, ClientInformation,
|
||||
ecs::query::Without,
|
||||
entity::{Dead, EntityKind, EntityUuid, Position, metadata::CustomName},
|
||||
pathfinder::goals::BlockPosGoal,
|
||||
prelude::PathfinderClientExt,
|
||||
world::MinecraftEntityId,
|
||||
};
|
||||
use mlua::{Error, Function, Lua, Result, Table, UserData, UserDataRef};
|
||||
|
||||
pub struct Client {
|
||||
pub inner: Option<AzaleaClient>,
|
||||
}
|
||||
|
||||
impl UserData for Client {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("pos", |lua, this| {
|
||||
let pos = this.inner.as_ref().unwrap().position();
|
||||
to_table(lua, pos.x, pos.y, pos.z)
|
||||
});
|
||||
}
|
||||
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_async_method("set_client_information", set_client_information);
|
||||
methods.add_method("get_entity", get_entity);
|
||||
methods.add_method_mut("get_entity_position", get_entity_position);
|
||||
methods.add_method_mut("goto", goto);
|
||||
methods.add_method_mut("stop", stop);
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_client_information(
|
||||
_lua: Lua,
|
||||
client: UserDataRef<Client>,
|
||||
client_information: Table,
|
||||
) -> Result<()> {
|
||||
client
|
||||
.inner
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_client_information(ClientInformation {
|
||||
view_distance: client_information.get("view_distance")?,
|
||||
..ClientInformation::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_entity(lua: &Lua, client: &Client, filter_fn: Function) -> Result<u32> {
|
||||
let mut ecs = client.inner.as_ref().unwrap().ecs.lock();
|
||||
let mut query = ecs.query_filtered::<(
|
||||
&MinecraftEntityId,
|
||||
&EntityUuid,
|
||||
&EntityKind,
|
||||
&Position,
|
||||
&CustomName,
|
||||
), Without<Dead>>();
|
||||
|
||||
for (&entity_id, entity_uuid, entity_kind, pos, custom_name) in query.iter(&ecs) {
|
||||
let entity = lua.create_table()?;
|
||||
|
||||
entity.set("id", entity_id.0)?;
|
||||
entity.set("uuid", entity_uuid.to_string())?;
|
||||
entity.set("kind", entity_kind.0.to_string())?;
|
||||
entity.set("pos", to_table(lua, pos.x, pos.y, pos.z)?)?;
|
||||
if let Some(n) = &**custom_name {
|
||||
entity.set("custom_name", n.to_string())?;
|
||||
}
|
||||
|
||||
if filter_fn.call::<bool>(entity).unwrap() {
|
||||
return Ok(entity_id.0);
|
||||
};
|
||||
}
|
||||
|
||||
Err(Error::RuntimeError("entity not found".to_string()))
|
||||
}
|
||||
|
||||
fn get_entity_position(lua: &Lua, client: &mut Client, entity_id: u32) -> Result<Table> {
|
||||
let client = client.inner.as_mut().unwrap();
|
||||
let entity = client
|
||||
.entity_by::<Without<Dead>, &MinecraftEntityId>(|query_entity_id: &&MinecraftEntityId| {
|
||||
query_entity_id.0 == entity_id
|
||||
})
|
||||
.unwrap();
|
||||
let pos = client.entity_component::<Position>(entity);
|
||||
to_table(lua, pos.x, pos.y, pos.z)
|
||||
}
|
||||
|
||||
fn goto(_lua: &Lua, client: &mut Client, pos_table: Table) -> Result<()> {
|
||||
let pos = from_table(&pos_table)?;
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
client
|
||||
.inner
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.goto(BlockPosGoal(BlockPos::new(
|
||||
pos.0 as i32,
|
||||
pos.1 as i32,
|
||||
pos.2 as i32,
|
||||
)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stop(_lua: &Lua, client: &mut Client, _: ()) -> Result<()> {
|
||||
client.inner.as_ref().unwrap().stop_pathfinding();
|
||||
Ok(())
|
||||
}
|
||||
68
src/scripting/client/mod.rs
Normal file
68
src/scripting/client/mod.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
mod pathfinding;
|
||||
mod state;
|
||||
|
||||
use super::{entity::Entity, position::Position};
|
||||
use azalea::{
|
||||
Client as AzaleaClient,
|
||||
ecs::query::Without,
|
||||
entity::{Dead, EntityKind, EntityUuid, Position as AzaleaPosition, metadata::CustomName},
|
||||
world::MinecraftEntityId,
|
||||
};
|
||||
use mlua::{Function, Lua, Result, UserData};
|
||||
|
||||
pub struct Client {
|
||||
pub inner: Option<AzaleaClient>,
|
||||
}
|
||||
|
||||
impl UserData for Client {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("position", |_, this| {
|
||||
let position = this.inner.as_ref().unwrap().position();
|
||||
Ok(Position {
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
z: position.z,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_async_method("set_client_information", state::set_client_information);
|
||||
methods.add_method("find_entities", find_entities);
|
||||
methods.add_method("stop_pathfinding", pathfinding::stop_pathfinding);
|
||||
methods.add_method_mut("goto", pathfinding::goto);
|
||||
}
|
||||
}
|
||||
|
||||
fn find_entities(_lua: &Lua, client: &Client, filter_fn: Function) -> Result<Vec<Entity>> {
|
||||
let mut matched = Vec::new();
|
||||
|
||||
let mut ecs = client.inner.as_ref().unwrap().ecs.lock();
|
||||
let mut query = ecs.query_filtered::<(
|
||||
&MinecraftEntityId,
|
||||
&EntityUuid,
|
||||
&EntityKind,
|
||||
&AzaleaPosition,
|
||||
&CustomName,
|
||||
), Without<Dead>>();
|
||||
|
||||
for (&id, uuid, kind, position, custom_name) in query.iter(&ecs) {
|
||||
let entity = Entity {
|
||||
id: id.0,
|
||||
uuid: uuid.to_string(),
|
||||
kind: kind.to_string(),
|
||||
position: Position {
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
z: position.z,
|
||||
},
|
||||
custom_name: custom_name.as_ref().map(ToString::to_string),
|
||||
};
|
||||
|
||||
if filter_fn.call::<bool>(entity.clone()).unwrap() {
|
||||
matched.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(matched)
|
||||
}
|
||||
22
src/scripting/client/pathfinding.rs
Normal file
22
src/scripting/client/pathfinding.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use super::{Client, Position};
|
||||
use azalea::{BlockPos, pathfinder::goals::BlockPosGoal, prelude::*};
|
||||
use mlua::{Lua, Result};
|
||||
|
||||
pub fn goto(_lua: &Lua, client: &mut Client, position: Position) -> Result<()> {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
client
|
||||
.inner
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.goto(BlockPosGoal(BlockPos::new(
|
||||
position.x as i32,
|
||||
position.y as i32,
|
||||
position.z as i32,
|
||||
)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> {
|
||||
client.inner.as_ref().unwrap().stop_pathfinding();
|
||||
Ok(())
|
||||
}
|
||||
21
src/scripting/client/state.rs
Normal file
21
src/scripting/client/state.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use super::Client;
|
||||
use azalea::ClientInformation;
|
||||
use mlua::{Lua, Result, Table, UserDataRef};
|
||||
|
||||
pub async fn set_client_information(
|
||||
_lua: Lua,
|
||||
client: UserDataRef<Client>,
|
||||
client_information: Table,
|
||||
) -> Result<()> {
|
||||
client
|
||||
.inner
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_client_information(ClientInformation {
|
||||
view_distance: client_information.get("view_distance")?,
|
||||
..ClientInformation::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
43
src/scripting/entity.rs
Normal file
43
src/scripting/entity.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use super::position::Position;
|
||||
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Entity {
|
||||
pub id: u32,
|
||||
pub uuid: String,
|
||||
pub kind: String,
|
||||
pub position: Position,
|
||||
pub custom_name: Option<String>,
|
||||
}
|
||||
|
||||
impl IntoLua for Entity {
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
let entity = lua.create_table()?;
|
||||
entity.set("id", self.id)?;
|
||||
entity.set("uuid", self.uuid)?;
|
||||
entity.set("kind", self.kind)?;
|
||||
entity.set("position", self.position)?;
|
||||
entity.set("custom_name", self.custom_name)?;
|
||||
Ok(Value::Table(entity))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromLua for Entity {
|
||||
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||
if let Value::Table(table) = value {
|
||||
Ok(Self {
|
||||
id: table.get("id")?,
|
||||
uuid: table.get("uuid")?,
|
||||
kind: table.get("kind")?,
|
||||
position: table.get("position")?,
|
||||
custom_name: table.get("custom_name")?,
|
||||
})
|
||||
} else {
|
||||
Err(mlua::Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "Position".to_string(),
|
||||
message: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use mlua::{Lua, Result, Table};
|
||||
|
||||
pub fn init(lua: &Lua, globals: &Table) -> Result<()> {
|
||||
pub fn register(lua: &Lua, globals: &Table) -> Result<()> {
|
||||
globals.set(
|
||||
"error",
|
||||
lua.create_function(|_, message: String| {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod client;
|
||||
pub mod entity;
|
||||
pub mod logging;
|
||||
pub mod position;
|
||||
|
||||
@@ -7,19 +8,19 @@ use mlua::Lua;
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Error {
|
||||
MissingGlobal(mlua::Error),
|
||||
ReadFile(std::io::Error),
|
||||
LoadChunk(mlua::Error),
|
||||
EvalChunk(mlua::Error),
|
||||
ExecChunk(mlua::Error),
|
||||
LoadChunk(mlua::Error),
|
||||
MissingPath(mlua::Error),
|
||||
ReadFile(std::io::Error),
|
||||
}
|
||||
|
||||
pub fn reload(lua: &Lua) -> Result<(), Error> {
|
||||
lua.load(
|
||||
&std::fs::read_to_string(
|
||||
lua.globals()
|
||||
.get::<String>("config_path")
|
||||
.map_err(Error::MissingGlobal)?,
|
||||
.get::<String>("script_path")
|
||||
.map_err(Error::MissingPath)?,
|
||||
)
|
||||
.map_err(Error::ReadFile)?,
|
||||
)
|
||||
|
||||
@@ -1,13 +1,36 @@
|
||||
use mlua::{Lua, Result, Table};
|
||||
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||
|
||||
pub fn to_table(lua: &Lua, x: f64, y: f64, z: f64) -> Result<Table> {
|
||||
let table = lua.create_table()?;
|
||||
table.set("x", x)?;
|
||||
table.set("y", y)?;
|
||||
table.set("z", z)?;
|
||||
Ok(table)
|
||||
#[derive(Clone)]
|
||||
pub struct Position {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
}
|
||||
|
||||
pub fn from_table(table: &Table) -> Result<(f64, f64, f64)> {
|
||||
Ok((table.get("x")?, table.get("y")?, table.get("z")?))
|
||||
impl IntoLua for Position {
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
let table = lua.create_table()?;
|
||||
table.set("x", self.x)?;
|
||||
table.set("y", self.y)?;
|
||||
table.set("z", self.z)?;
|
||||
Ok(Value::Table(table))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromLua for Position {
|
||||
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||
if let Value::Table(table) = value {
|
||||
Ok(Self {
|
||||
x: table.get("x")?,
|
||||
y: table.get("y")?,
|
||||
z: table.get("z")?,
|
||||
})
|
||||
} else {
|
||||
Err(mlua::Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "Position".to_string(),
|
||||
message: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user