feat: expose command sender to code from in-game

This commit is contained in:
Ryan 2025-02-21 23:34:25 -05:00
parent aadc9a919e
commit 3fc917efae
Signed by: ErrorNoInternet
GPG Key ID: 2486BFB7B1E6A4A3
4 changed files with 35 additions and 25 deletions

View File

@ -4,7 +4,7 @@ function look_at_player(name)
player.position.y = player.position.y + 1 player.position.y = player.position.y + 1
client:look_at(player.position) client:look_at(player.position)
else else
client:chat("player not found!") client:chat(string.format("/w %s player not found!", sender))
end end
end end
@ -13,6 +13,6 @@ function goto_player(name)
if player then if player then
client:goto(player.position) client:goto(player.position)
else else
client:chat("player not found!") client:chat(string.format("/w %s player not found!", sender))
end end
end end

View File

@ -2,11 +2,7 @@ use crate::{
State, State,
lua::{eval, exec, reload}, lua::{eval, exec, reload},
}; };
use azalea::{ use azalea::{brigadier::prelude::*, chat::ChatPacket, prelude::*};
GameProfileComponent, brigadier::prelude::*, chat::ChatPacket, entity::metadata::Player,
prelude::*,
};
use bevy_ecs::{entity::Entity, query::With};
use futures::lock::Mutex; use futures::lock::Mutex;
pub type Ctx = CommandContext<Mutex<CommandSource>>; pub type Ctx = CommandContext<Mutex<CommandSource>>;
@ -36,14 +32,6 @@ impl CommandSource {
); );
} }
} }
pub fn _entity(&mut self) -> Option<Entity> {
let username = self.message.username()?;
self.client
.entity_by::<With<Player>, &GameProfileComponent>(|profile: &&GameProfileComponent| {
profile.name == username
})
}
} }
pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) { pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
@ -51,7 +39,10 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
let source = ctx.source.clone(); let source = ctx.source.clone();
tokio::spawn(async move { tokio::spawn(async move {
let source = source.lock().await; let source = source.lock().await;
source.reply(&format!("{:?}", reload(&source.state.lua))); source.reply(&format!(
"{:?}",
reload(&source.state.lua, source.message.username())
));
}); });
1 1
})); }));
@ -62,7 +53,10 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
let code = get_string(ctx, "code").expect("argument should exist"); let code = get_string(ctx, "code").expect("argument should exist");
tokio::spawn(async move { tokio::spawn(async move {
let source = source.lock().await; let source = source.lock().await;
source.reply(&format!("{:?}", eval(&source.state.lua, &code).await)); source.reply(&format!(
"{:?}",
eval(&source.state.lua, &code, source.message.username()).await
));
}); });
1 1
})), })),
@ -74,7 +68,10 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
let code = get_string(ctx, "code").expect("argument should exist"); let code = get_string(ctx, "code").expect("argument should exist");
tokio::spawn(async move { tokio::spawn(async move {
let source = source.lock().await; let source = source.lock().await;
source.reply(&format!("{:?}", exec(&source.state.lua, &code).await)); source.reply(&format!(
"{:?}",
exec(&source.state.lua, &code, source.message.username()).await
));
}); });
1 1
})), })),

View File

@ -12,7 +12,7 @@ pub async fn serve(
let path = request.uri().path().to_owned(); let path = request.uri().path().to_owned();
Ok(match (request.method(), path.as_str()) { Ok(match (request.method(), path.as_str()) {
(&Method::POST, "/reload") => match reload(&state.lua) { (&Method::POST, "/reload") => match reload(&state.lua, None) {
Ok(()) => Response::new(empty()), Ok(()) => Response::new(empty()),
Err(error) => status_code_response( Err(error) => status_code_response(
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
@ -24,8 +24,8 @@ pub async fn serve(
let bytes = request.into_body().collect().await?.to_bytes(); let bytes = request.into_body().collect().await?.to_bytes();
match std::str::from_utf8(&bytes) { match std::str::from_utf8(&bytes) {
Ok(code) => Response::new(full(match path.as_str() { Ok(code) => Response::new(full(match path.as_str() {
"/eval" => format!("{:#?}", eval(&state.lua, code).await), "/eval" => format!("{:#?}", eval(&state.lua, code, None).await),
"/exec" => format!("{:#?}", exec(&state.lua, code).await), "/exec" => format!("{:#?}", exec(&state.lua, code, None).await),
_ => unreachable!(), _ => unreachable!(),
})), })),
Err(error) => status_code_response( Err(error) => status_code_response(

View File

@ -12,6 +12,7 @@ use mlua::{Lua, Table};
#[derive(Debug)] #[derive(Debug)]
#[allow(dead_code)] #[allow(dead_code)]
pub enum Error { pub enum Error {
CreateEnv(mlua::Error),
EvalChunk(mlua::Error), EvalChunk(mlua::Error),
ExecChunk(mlua::Error), ExecChunk(mlua::Error),
LoadChunk(mlua::Error), LoadChunk(mlua::Error),
@ -32,7 +33,7 @@ pub fn register_functions(lua: &Lua, globals: &Table) -> mlua::Result<()> {
logging::register_functions(lua, globals) logging::register_functions(lua, globals)
} }
pub fn reload(lua: &Lua) -> Result<(), Error> { pub fn reload(lua: &Lua, sender: Option<String>) -> Result<(), Error> {
lua.load( lua.load(
&std::fs::read_to_string( &std::fs::read_to_string(
lua.globals() lua.globals()
@ -41,17 +42,29 @@ pub fn reload(lua: &Lua) -> Result<(), Error> {
) )
.map_err(Error::ReadFile)?, .map_err(Error::ReadFile)?,
) )
.set_environment(create_env(lua, sender)?)
.exec() .exec()
.map_err(Error::LoadChunk) .map_err(Error::LoadChunk)
} }
pub async fn eval(lua: &Lua, code: &str) -> Result<String, Error> { pub async fn eval(lua: &Lua, code: &str, sender: Option<String>) -> Result<String, Error> {
lua.load(code) lua.load(code)
.set_environment(create_env(lua, sender)?)
.eval_async::<String>() .eval_async::<String>()
.await .await
.map_err(Error::EvalChunk) .map_err(Error::EvalChunk)
} }
pub async fn exec(lua: &Lua, code: &str) -> Result<(), Error> { pub async fn exec(lua: &Lua, code: &str, sender: Option<String>) -> Result<(), Error> {
lua.load(code).exec_async().await.map_err(Error::ExecChunk) lua.load(code)
.set_environment(create_env(lua, sender)?)
.exec_async()
.await
.map_err(Error::ExecChunk)
}
fn create_env(lua: &Lua, sender: Option<String>) -> Result<Table, Error> {
let globals = lua.globals();
globals.set("sender", sender).map_err(Error::CreateEnv)?;
Ok(globals)
} }