fixed the event handler registration stuff

This commit is contained in:
Luuk van Oijen
2023-11-13 16:57:45 +01:00
parent a0db8aa8be
commit e781bbac8e
4 changed files with 63 additions and 35 deletions

View File

@@ -1,8 +1,13 @@
print("test from lua")
print("Player count: " .. MP.GetPlayerCount())
function onPluginLoaded()
function onPluginLoaded2()
print("HI!")
end
MP.RegisterEventHandler("onPluginLoaded", "onPluginLoaded")
function onPlayerAuthenticated2(name)
print("hi welcome mista " .. name)
end
MP.RegisterEventHandler("onPluginLoaded", "onPluginLoaded2")
MP.RegisterEventHandler("onPlayerAuthenticated", "onPlayerAuthenticated2")

View File

@@ -363,6 +363,13 @@ impl Server {
match event {
ServerBoundPluginEvent::PluginLoaded => plugin.send_event(PluginBoundPluginEvent::CallEventHandler((ScriptEvent::OnPluginLoaded, Vec::new()))).await,
ServerBoundPluginEvent::RequestPlayerCount(responder) => { let _ = responder.send(PluginBoundPluginEvent::PlayerCount(self.clients.len())); }
ServerBoundPluginEvent::RequestPlayers(responder) => {
let mut players = HashMap::new();
for client in &self.clients {
players.insert(client.id, client.get_name().to_string());
}
let _ = responder.send(PluginBoundPluginEvent::Players(players));
}
_ => {},
}
}

View File

@@ -6,7 +6,8 @@ use super::{
Argument
};
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use tokio::sync::mpsc::{Sender, Receiver};
use tokio::sync::oneshot;
@@ -17,12 +18,16 @@ use mlua::{UserData, UserDataMethods, Value, Function, Variadic};
#[derive(Clone)]
struct Context {
tx: Arc<Sender<ServerBoundPluginEvent>>,
handlers: Arc<Mutex<HashMap<String, String>>>,
}
impl Context {
fn new(tx: Arc<Sender<ServerBoundPluginEvent>>) -> Self {
Self {
tx,
handlers: Arc::new(Mutex::new(HashMap::new())),
}
}
}
@@ -43,8 +48,7 @@ impl UserData for Context {
methods.add_function("RegisterEventHandler", |lua, (event_name, handler_name): (String, String)| {
debug!("Event handler registered: {} (EVENT) = {} (LUA)", event_name, handler_name);
let me: Context = lua.globals().get("MP")?;
// TODO: Figure out how to handle these errors (?)
let _ = me.tx.blocking_send(ServerBoundPluginEvent::RegisterEventHandler((event_name, handler_name)));
me.handlers.lock().expect("Lock is poisoned!").insert(event_name, handler_name);
Ok(())
});
@@ -70,23 +74,27 @@ impl UserData for Context {
}
});
// methods.add_function("GetPlayers", |lua, ()| {
// let me: Context = lua.globals().get("MP")?;
// let (tx, rx) = oneshot::channel();
// if let Err(e) = me.tx.blocking_send(ServerBoundPluginEvent::RequestPlayerCount(tx)) {
// error!("Failed to send packet: {:?}", e);
// }
// let message = rx.blocking_recv();
// if let Ok(message) = message {
// if let PluginBoundPluginEvent::PlayerCount(player_count) = message {
// Ok(player_count)
// } else {
// unreachable!() // This really should never be reachable
// }
// } else {
// todo!("Receiving a response from the server failed! How?")
// }
// });
methods.add_function("GetPlayers", |lua, ()| {
let me: Context = lua.globals().get("MP")?;
let (tx, rx) = oneshot::channel();
if let Err(e) = me.tx.blocking_send(ServerBoundPluginEvent::RequestPlayers(tx)) {
error!("Failed to send packet: {:?}", e);
}
let message = rx.blocking_recv();
if let Ok(message) = message {
if let PluginBoundPluginEvent::Players(players) = message {
let table = lua.create_table()?;
for (id, name) in players {
table.set(id, name)?;
}
Ok(table)
} else {
unreachable!() // This really should never be reachable
}
} else {
todo!("Receiving a response from the server failed! How?")
}
});
}
}
@@ -128,19 +136,25 @@ impl Backend for BackendLua {
fn call_event_handler(&mut self, event: ScriptEvent, args: Vec<Argument>) {
let event_name = match event {
ScriptEvent::OnPluginLoaded => "onPluginLoaded",
ScriptEvent::OnPlayerAuthenticated => "onPlayerAuthenticated",
};
let func: LuaResult<Function> = self.lua.globals().get(event_name);
if let Ok(func) = func {
let mapped_args = args.into_iter().map(|arg| {
match arg {
Argument::String(s) => if let Ok(lua_str) = self.lua.create_string(&s) { Some(Value::String(lua_str)) } else { None },
Argument::Boolean(b) => Some(Value::Boolean(b)),
Argument::Number(f) => Some(Value::Number(f as f64)),
// TODO: Error handling
let ctx: Context = self.lua.globals().get("MP").expect("MP is missing!");
let lock = ctx.handlers.lock().expect("Mutex is poisoned!");
if let Some(handler_name) = lock.get(event_name) {
let func: LuaResult<Function> = self.lua.globals().get(handler_name.clone());
if let Ok(func) = func {
let mapped_args = args.into_iter().map(|arg| {
match arg {
Argument::String(s) => if let Ok(lua_str) = self.lua.create_string(&s) { Some(Value::String(lua_str)) } else { None },
Argument::Boolean(b) => Some(Value::Boolean(b)),
Argument::Number(f) => Some(Value::Number(f as f64)),
}
}).filter(|v| v.is_some());
if let Err(e) = func.call::<_, ()>(Variadic::from_iter(mapped_args)) {
error!("[LUA] {}", e);
}
}).filter(|v| v.is_some());
if let Err(e) = func.call::<_, ()>(Variadic::from_iter(mapped_args)) {
error!("[LUA] {}", e);
}
}
}

View File

@@ -1,8 +1,8 @@
pub mod backend_lua;
use std::sync::Arc;
use std::collections::HashMap;
use tokio::runtime::Runtime;
use tokio::sync::Mutex;
use tokio::sync::mpsc::{self, Sender, Receiver};
use tokio::sync::oneshot;
@@ -28,21 +28,23 @@ pub enum Argument {
#[derive(Debug)]
pub enum ScriptEvent {
OnPluginLoaded,
OnPlayerAuthenticated,
}
#[derive(Debug)]
pub enum PluginBoundPluginEvent {
CallEventHandler((ScriptEvent, Vec<Argument>)),
PlayerCount(usize),
Players(HashMap<u8, String>),
}
#[derive(Debug)]
pub enum ServerBoundPluginEvent {
PluginLoaded,
/// Arguments: (event name, handler function name)
RegisterEventHandler((String, String)),
RequestPlayerCount(oneshot::Sender<PluginBoundPluginEvent>),
RequestPlayers(oneshot::Sender<PluginBoundPluginEvent>),
}
pub struct Plugin {