diff --git a/Resources/Server/TestPlugin/main.lua b/Resources/Server/TestPlugin/main.lua index 0c50d79..a66b4e9 100644 --- a/Resources/Server/TestPlugin/main.lua +++ b/Resources/Server/TestPlugin/main.lua @@ -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") diff --git a/src/server/mod.rs b/src/server/mod.rs index 4883c89..d18a4db 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -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)); + } _ => {}, } } diff --git a/src/server/plugins/backend_lua.rs b/src/server/plugins/backend_lua.rs index 3513bf4..06c7b3b 100644 --- a/src/server/plugins/backend_lua.rs +++ b/src/server/plugins/backend_lua.rs @@ -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>, + + handlers: Arc>>, } impl Context { fn new(tx: Arc>) -> 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) { let event_name = match event { ScriptEvent::OnPluginLoaded => "onPluginLoaded", + ScriptEvent::OnPlayerAuthenticated => "onPlayerAuthenticated", }; - let func: LuaResult = 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 = 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); } } } diff --git a/src/server/plugins/mod.rs b/src/server/plugins/mod.rs index ca7c93c..362d7b3 100644 --- a/src/server/plugins/mod.rs +++ b/src/server/plugins/mod.rs @@ -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)), + PlayerCount(usize), + Players(HashMap), } #[derive(Debug)] pub enum ServerBoundPluginEvent { PluginLoaded, - /// Arguments: (event name, handler function name) - RegisterEventHandler((String, String)), RequestPlayerCount(oneshot::Sender), + RequestPlayers(oneshot::Sender), } pub struct Plugin {