feat(client): add remaining miscellaneous fields and methods
This commit is contained in:
parent
2e1736af25
commit
8e89f8e9ea
@ -34,7 +34,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let username = globals.get::<String>("USERNAME")?;
|
let username = globals.get::<String>("USERNAME")?;
|
||||||
|
|
||||||
globals.set("script_path", script_path)?;
|
globals.set("script_path", script_path)?;
|
||||||
scripting::logging::register(&lua, &globals)?;
|
scripting::register_functions(&lua, &globals)?;
|
||||||
|
|
||||||
let mut commands = CommandDispatcher::new();
|
let mut commands = CommandDispatcher::new();
|
||||||
register(&mut commands);
|
register(&mut commands);
|
||||||
|
22
src/scripting/client/interaction.rs
Normal file
22
src/scripting/client/interaction.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use super::{Client, Vec3};
|
||||||
|
use azalea::{BlockPos, world::MinecraftEntityId};
|
||||||
|
use mlua::{Lua, Result};
|
||||||
|
|
||||||
|
pub fn attack(_lua: &Lua, client: &mut Client, entity_id: u32) -> Result<()> {
|
||||||
|
client
|
||||||
|
.inner
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.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(
|
||||||
|
position.x as i32,
|
||||||
|
position.y as i32,
|
||||||
|
position.z as i32,
|
||||||
|
));
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,36 +1,104 @@
|
|||||||
mod pathfinding;
|
mod interaction;
|
||||||
|
mod movement;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
use super::{entity::Entity, position::Position};
|
use super::{direction::Direction, entity::Entity, hunger::Hunger, vec3::Vec3};
|
||||||
use azalea::{
|
use azalea::{
|
||||||
Client as AzaleaClient,
|
Client as AzaleaClient,
|
||||||
ecs::query::Without,
|
ecs::query::Without,
|
||||||
entity::{Dead, EntityKind, EntityUuid, Position as AzaleaPosition, metadata::CustomName},
|
entity::{
|
||||||
|
Dead, EntityKind, EntityUuid, Position as AzaleaPosition,
|
||||||
|
metadata::{AirSupply, CustomName, Score},
|
||||||
|
},
|
||||||
world::MinecraftEntityId,
|
world::MinecraftEntityId,
|
||||||
};
|
};
|
||||||
use mlua::{Function, Lua, Result, UserData};
|
use mlua::{Function, Lua, Result, UserData, UserDataFields, UserDataMethods};
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
pub inner: Option<AzaleaClient>,
|
pub inner: Option<AzaleaClient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserData for Client {
|
impl UserData for Client {
|
||||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
fn add_fields<F: UserDataFields<Self>>(f: &mut F) {
|
||||||
fields.add_field_method_get("position", |_, this| {
|
f.add_field_method_get("air_supply", |_, this| {
|
||||||
let position = this.inner.as_ref().unwrap().position();
|
Ok(this.inner.as_ref().unwrap().component::<AirSupply>().0)
|
||||||
Ok(Position {
|
});
|
||||||
x: position.x,
|
|
||||||
y: position.y,
|
f.add_field_method_get("direction", |_, this| {
|
||||||
z: position.z,
|
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("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())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: UserDataMethods<Self>>(m: &mut M) {
|
||||||
methods.add_async_method("set_client_information", state::set_client_information);
|
m.add_async_method("set_client_information", state::set_client_information);
|
||||||
methods.add_method("find_entities", find_entities);
|
m.add_method("chat", chat);
|
||||||
methods.add_method("stop_pathfinding", pathfinding::stop_pathfinding);
|
m.add_method("find_entities", find_entities);
|
||||||
methods.add_method_mut("goto", pathfinding::goto);
|
m.add_method("stop_pathfinding", movement::stop_pathfinding);
|
||||||
|
m.add_method_mut("attack", interaction::attack);
|
||||||
|
m.add_method_mut("block_interact", interaction::block_interact);
|
||||||
|
m.add_method_mut("goto", movement::goto);
|
||||||
|
m.add_method_mut("goto_without_mining", movement::goto_without_mining);
|
||||||
|
m.add_method_mut("jump", movement::jump);
|
||||||
|
m.add_method_mut("look_at", movement::look_at);
|
||||||
|
m.add_method_mut("set_direction", movement::set_direction);
|
||||||
|
m.add_method_mut("set_jumping", movement::set_jumping);
|
||||||
|
m.add_method_mut("sprint", movement::sprint);
|
||||||
|
m.add_method_mut("walk", movement::walk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +119,7 @@ fn find_entities(_lua: &Lua, client: &Client, filter_fn: Function) -> Result<Vec
|
|||||||
id: id.0,
|
id: id.0,
|
||||||
uuid: uuid.to_string(),
|
uuid: uuid.to_string(),
|
||||||
kind: kind.to_string(),
|
kind: kind.to_string(),
|
||||||
position: Position {
|
position: Vec3 {
|
||||||
x: position.x,
|
x: position.x,
|
||||||
y: position.y,
|
y: position.y,
|
||||||
z: position.z,
|
z: position.z,
|
||||||
@ -66,3 +134,8 @@ fn find_entities(_lua: &Lua, client: &Client, filter_fn: Function) -> Result<Vec
|
|||||||
|
|
||||||
Ok(matched)
|
Ok(matched)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn chat(_lua: &Lua, client: &Client, message: String) -> Result<()> {
|
||||||
|
client.inner.as_ref().unwrap().chat(&message);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
90
src/scripting/client/movement.rs
Normal file
90
src/scripting/client/movement.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use super::{Client, Vec3};
|
||||||
|
use azalea::{
|
||||||
|
BlockPos, SprintDirection, WalkDirection, pathfinder::goals::BlockPosGoal, prelude::*,
|
||||||
|
};
|
||||||
|
use mlua::{Lua, Result};
|
||||||
|
|
||||||
|
pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> {
|
||||||
|
client.inner.as_ref().unwrap().stop_pathfinding();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn goto(_lua: &Lua, client: &mut Client, position: Vec3) -> 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 goto_without_mining(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> {
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
client
|
||||||
|
.inner
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.goto_without_mining(BlockPosGoal(BlockPos::new(
|
||||||
|
position.x as i32,
|
||||||
|
position.y as i32,
|
||||||
|
position.z as i32,
|
||||||
|
)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jump(_lua: &Lua, client: &mut Client, _: ()) -> Result<()> {
|
||||||
|
client.inner.as_mut().unwrap().jump();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_direction(_lua: &Lua, client: &mut Client, direction: (f32, f32)) -> Result<()> {
|
||||||
|
client
|
||||||
|
.inner
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.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);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sprint(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> {
|
||||||
|
client.inner.as_mut().unwrap().sprint(match direction {
|
||||||
|
5 => SprintDirection::ForwardRight,
|
||||||
|
6 => SprintDirection::ForwardLeft,
|
||||||
|
_ => SprintDirection::Forward,
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk(_lua: &Lua, client: &mut Client, direction: u8) -> Result<()> {
|
||||||
|
client.inner.as_mut().unwrap().walk(match direction {
|
||||||
|
1 => WalkDirection::Forward,
|
||||||
|
2 => WalkDirection::Backward,
|
||||||
|
3 => WalkDirection::Left,
|
||||||
|
4 => WalkDirection::Right,
|
||||||
|
5 => WalkDirection::ForwardRight,
|
||||||
|
6 => WalkDirection::ForwardLeft,
|
||||||
|
7 => WalkDirection::BackwardRight,
|
||||||
|
8 => WalkDirection::BackwardLeft,
|
||||||
|
_ => WalkDirection::None,
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,22 +0,0 @@
|
|||||||
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(())
|
|
||||||
}
|
|
33
src/scripting/direction.rs
Normal file
33
src/scripting/direction.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Direction {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoLua for Direction {
|
||||||
|
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||||
|
let table = lua.create_table()?;
|
||||||
|
table.set("x", self.x)?;
|
||||||
|
table.set("y", self.y)?;
|
||||||
|
Ok(Value::Table(table))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromLua for Direction {
|
||||||
|
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")?,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(mlua::Error::FromLuaConversionError {
|
||||||
|
from: value.type_name(),
|
||||||
|
to: "Direction".to_string(),
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use super::position::Position;
|
use super::vec3::Vec3;
|
||||||
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -6,7 +6,7 @@ pub struct Entity {
|
|||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub uuid: String,
|
pub uuid: String,
|
||||||
pub kind: String,
|
pub kind: String,
|
||||||
pub position: Position,
|
pub position: Vec3,
|
||||||
pub custom_name: Option<String>,
|
pub custom_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
src/scripting/hunger.rs
Normal file
33
src/scripting/hunger.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Hunger {
|
||||||
|
pub food: u32,
|
||||||
|
pub saturation: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoLua for Hunger {
|
||||||
|
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||||
|
let table = lua.create_table()?;
|
||||||
|
table.set("food", self.food)?;
|
||||||
|
table.set("saturation", self.saturation)?;
|
||||||
|
Ok(Value::Table(table))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromLua for Hunger {
|
||||||
|
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||||
|
if let Value::Table(table) = value {
|
||||||
|
Ok(Self {
|
||||||
|
food: table.get("food")?,
|
||||||
|
saturation: table.get("saturation")?,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(mlua::Error::FromLuaConversionError {
|
||||||
|
from: value.type_name(),
|
||||||
|
to: "Hunger".to_string(),
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use mlua::{Lua, Result, Table};
|
use mlua::{Lua, Result, Table};
|
||||||
|
|
||||||
pub fn register(lua: &Lua, globals: &Table) -> Result<()> {
|
pub fn register_functions(lua: &Lua, globals: &Table) -> Result<()> {
|
||||||
globals.set(
|
globals.set(
|
||||||
"error",
|
"error",
|
||||||
lua.create_function(|_, message: String| {
|
lua.create_function(|_, message: String| {
|
||||||
@ -37,5 +37,6 @@ pub fn register(lua: &Lua, globals: &Table) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
pub mod client;
|
pub mod client;
|
||||||
|
pub mod direction;
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
|
pub mod hunger;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod position;
|
pub mod vec3;
|
||||||
|
|
||||||
use mlua::Lua;
|
use mlua::{Lua, Table};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -15,6 +17,18 @@ pub enum Error {
|
|||||||
ReadFile(std::io::Error),
|
ReadFile(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_functions(lua: &Lua, globals: &Table) -> mlua::Result<()> {
|
||||||
|
globals.set(
|
||||||
|
"sleep",
|
||||||
|
lua.create_async_function(async |_, duration: u64| {
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(duration)).await;
|
||||||
|
Ok(())
|
||||||
|
})?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
logging::register_functions(lua, globals)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reload(lua: &Lua) -> Result<(), Error> {
|
pub fn reload(lua: &Lua) -> Result<(), Error> {
|
||||||
lua.load(
|
lua.load(
|
||||||
&std::fs::read_to_string(
|
&std::fs::read_to_string(
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
use mlua::{FromLua, IntoLua, Lua, Result, Value};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Position {
|
pub struct Vec3 {
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
pub y: f64,
|
pub y: f64,
|
||||||
pub z: f64,
|
pub z: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoLua for Position {
|
impl IntoLua for Vec3 {
|
||||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||||
let table = lua.create_table()?;
|
let table = lua.create_table()?;
|
||||||
table.set("x", self.x)?;
|
table.set("x", self.x)?;
|
||||||
@ -17,7 +17,7 @@ impl IntoLua for Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromLua for Position {
|
impl FromLua for Vec3 {
|
||||||
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||||
if let Value::Table(table) = value {
|
if let Value::Table(table) = value {
|
||||||
Ok(Self {
|
Ok(Self {
|
Loading…
x
Reference in New Issue
Block a user