diff --git a/Cargo.lock b/Cargo.lock index 4f258eb..038450a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3335,6 +3335,7 @@ version = "0.3.0" dependencies = [ "async-trait", "bytes", + "byteserde", "clap", "env_logger", "literustlib", diff --git a/rc_multiplayer/Cargo.toml b/rc_multiplayer/Cargo.toml index d68c54f..33633ba 100644 --- a/rc_multiplayer/Cargo.toml +++ b/rc_multiplayer/Cargo.toml @@ -15,6 +15,7 @@ clap.workspace = true oj_rc_core = { version = "*", path = "../rc_core" } async-trait.workspace = true bytes = "1.10" +byteserde = "0.6.2" literustlib_server = { version = "0.1", path = "../../LiteRustLib/server" } literustlib = { version = "0.1", path = "../../LiteRustLib" } diff --git a/rc_multiplayer/src/events/mod.rs b/rc_multiplayer/src/events/mod.rs new file mode 100644 index 0000000..25d45e6 --- /dev/null +++ b/rc_multiplayer/src/events/mod.rs @@ -0,0 +1,6 @@ +mod validate_game_guid; + +pub async fn handler(init_ctx: &crate::InitConfig) -> crate::handler::LnlEventHandler { + crate::handler::LnlEventHandler::new() + .add(validate_game_guid::handler(init_ctx)) +} diff --git a/rc_multiplayer/src/events/validate_game_guid.rs b/rc_multiplayer/src/events/validate_game_guid.rs new file mode 100644 index 0000000..f73ab13 --- /dev/null +++ b/rc_multiplayer/src/events/validate_game_guid.rs @@ -0,0 +1,25 @@ +pub struct AuthUserGame { + +} + +pub(super) fn handler(init_ctx: &crate::InitConfig) -> crate::handlers::simple_typed::SimpleRlnl { + crate::handlers::simple_typed::SimpleRlnl::new(AuthUserGame::new(init_ctx)) +} + +impl AuthUserGame { + fn new(_init_ctx: &crate::InitConfig) -> Self { + Self { + + } + } +} + +#[async_trait::async_trait] +impl crate::handlers::simple_typed::RlnlEventCodeHandler for AuthUserGame { + type In = rlnl::events::loading::GameGuidInfo; + const CODE: rlnl::event_code::NetworkEvent = rlnl::event_code::NetworkEvent::ValidateGameGuid; + + async fn handle(&self, data: Self::In, peer: &std::sync::Arc>, user: &crate::UserData, sender: &literustlib_server::DataSender) { + log::debug!("Got {:?} event with data {:?}", Self::CODE, data); + } +} diff --git a/rc_multiplayer/src/handler.rs b/rc_multiplayer/src/handler.rs index a5fdb18..5f1ed9f 100644 --- a/rc_multiplayer/src/handler.rs +++ b/rc_multiplayer/src/handler.rs @@ -1,15 +1,18 @@ pub struct LnlEventHandler { - event_handlers: std::collections::HashMap>, + event_handlers: std::collections::HashMap>, } impl LnlEventHandler { - pub async fn new(init_ctx: &crate::InitConfig) -> Self { - let mut event_handlers = std::collections::HashMap::new(); - // init event code handlers + pub fn new() -> Self { Self { - event_handlers + event_handlers: std::collections::HashMap::new(), } } + + pub fn add(mut self, handler: H) -> Self { + self.event_handlers.insert(H::CODE, Box::new(handler)); + self + } } #[async_trait::async_trait] @@ -19,7 +22,7 @@ impl literustlib_server::EventHandler for LnlEventHandler { async fn on_receive(&self, data: Self::PacketData, _header: &literustlib::packet::Header, peer: &std::sync::Arc< literustlib_server::Connection>, user: &Self::UserData, sender: &literustlib_server::DataSender) { log::debug!("Got event {:?} (len: {}) from connection id {}", data.variant, data.data.len(), peer.id()); - if let Some(handler) = self.event_handlers.get(&(data.variant as u16)) { + if let Some(handler) = self.event_handlers.get(&(data.variant as i16)) { handler.handle(&data.data, peer, user, sender).await; } else { #[cfg(debug_assertions)] @@ -38,7 +41,7 @@ impl literustlib_server::EventHandler for LnlEventHandler { //let mut buf = Vec::new(); //literustlib::packet::Packet::with_data(literustlib::packet::Property::Reliable, &[9, 0, 0, 0, 0, 0]).dump(&mut buf).unwrap_or_default(); //socket.send_to(&buf, addr).await.unwrap_or_default(); - Some(()) + Some(crate::UserData::new()) } async fn on_connect_done(&self, peer: &std::sync::Arc< literustlib_server::Connection>, _user: &Self::UserData, sender: &literustlib_server::DataSender) { @@ -65,7 +68,6 @@ impl literustlib::packet::PacketData for EventData { fn parse(bytes: bytes::Bytes, _header: &literustlib::packet::Header) -> std::io::Result { if bytes.len() >= 6 { let data = bytes.slice(6..); - let slice: &[u8] = &bytes[0..6]; let net_message_num = i16::from_le_bytes([bytes[0], bytes[1]]); let net_message_type = crate::data::MessageType::from_i16(net_message_num).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Unsupported message type {}", net_message_num)))?; let event_code = i16::from_le_bytes([bytes[2], bytes[3]]); diff --git a/rc_multiplayer/src/handlers/mod.rs b/rc_multiplayer/src/handlers/mod.rs new file mode 100644 index 0000000..f0b1ad9 --- /dev/null +++ b/rc_multiplayer/src/handlers/mod.rs @@ -0,0 +1 @@ +pub mod simple_typed; diff --git a/rc_multiplayer/src/handlers/simple_typed.rs b/rc_multiplayer/src/handlers/simple_typed.rs new file mode 100644 index 0000000..f8622f0 --- /dev/null +++ b/rc_multiplayer/src/handlers/simple_typed.rs @@ -0,0 +1,37 @@ +pub struct SimpleRlnl, H: RlnlEventCodeHandler> { + //_in: std::marker::PhantomData, + //_out: std::marker::PhantomData, + handler: H, +} + +impl , H: RlnlEventCodeHandler> SimpleRlnl { + pub fn new(inner: H) -> Self { + Self { + handler: inner, + } + } +} + +#[async_trait::async_trait] +pub trait RlnlEventCodeHandler: Sync + Send { + type In: byteserde::des_slice::ByteDeserializeSlice; + //type Out: byteserde::ser_heap::ByteSerializeHeap; + const CODE: rlnl::event_code::NetworkEvent; + + async fn handle(&self, data: Self::In, peer: &std::sync::Arc>, user: &crate::UserData, sender: &literustlib_server::DataSender); +} + +#[async_trait::async_trait] +impl , H: RlnlEventCodeHandler> crate::EventCodeHandler for SimpleRlnl { + async fn handle(&self, data: &bytes::Bytes, peer: &std::sync::Arc>, user: &crate::UserData, sender: &literustlib_server::DataSender) { + let mut des = byteserde::des_slice::ByteDeserializerSlice::new(&data); + let rlnl_data = In::byte_deserialize(&mut des).expect("Bad serialization"); + self.handler.handle(rlnl_data, peer, user, sender).await; + } +} + +impl , H: RlnlEventCodeHandler> crate::EventCode for SimpleRlnl { + const CODE: i16 = H::CODE as i16; +} + + diff --git a/rc_multiplayer/src/main.rs b/rc_multiplayer/src/main.rs index 1241c60..a424a09 100644 --- a/rc_multiplayer/src/main.rs +++ b/rc_multiplayer/src/main.rs @@ -1,8 +1,11 @@ mod cli; mod handler; mod traits; -pub use traits::{EventCodeHandler, UserData, PacketData}; +pub use traits::{EventCodeHandler, UserData, PacketData, EventCode}; mod data; +mod events; +mod handlers; +mod user; pub struct InitConfig { pub config: oj_rc_core::persist::config::ConfigImpl, @@ -27,7 +30,7 @@ async fn main() -> std::io::Result<()> { }; let mtu = oj_rc_core::ConfigProvider::<()>::network_config(&init_ctx.config).max_packet_size; - let event_handler = handler::LnlEventHandler::new(&init_ctx).await; + let event_handler = events::handler(&init_ctx).await; let server = literustlib_server::Server::new(event_handler, (args.ip, args.port), mtu).await.expect("Bad server"); server.listen().await } diff --git a/rc_multiplayer/src/traits.rs b/rc_multiplayer/src/traits.rs index 9f975c2..5bee4b7 100644 --- a/rc_multiplayer/src/traits.rs +++ b/rc_multiplayer/src/traits.rs @@ -1,7 +1,11 @@ -pub type UserData = (); +pub type UserData = crate::user::User; pub type PacketData = crate::handler::EventData; #[async_trait::async_trait] pub trait EventCodeHandler: Send + Sync { async fn handle(&self, data: &bytes::Bytes, peer: &std::sync::Arc>, user: &UserData, sender: &literustlib_server::DataSender); } + +pub trait EventCode: EventCodeHandler { + const CODE: i16; +} diff --git a/rc_multiplayer/src/user.rs b/rc_multiplayer/src/user.rs new file mode 100644 index 0000000..f6d8ae7 --- /dev/null +++ b/rc_multiplayer/src/user.rs @@ -0,0 +1,29 @@ +pub struct User { + state: tokio::sync::RwLock, +} + +impl User { + pub fn new() -> Self { + Self { + state: tokio::sync::RwLock::new(UserState::Connecting), + } + } + + pub async fn authenticate(&self, info: rlnl::events::loading::GameGuidInfo) -> bool { + *self.state.write().await = UserState::Authenticated(UserInfo { + game: info.game_guid.0, + username: info.player_name.0, + }); + true + } +} + +enum UserState { + Connecting, + Authenticated(UserInfo), +} + +pub struct UserInfo { + pub game: String, + pub username: String, +}