From aa2be43f4e419b2382dc02e8da9750e050e0943a12724af35f38f950c972c7a9 Mon Sep 17 00:00:00 2001 From: raven <7156279+RavenX8@users.noreply.github.com> Date: Sat, 7 Jun 2025 00:36:02 -0400 Subject: [PATCH] Refactor Updated handlers by spliting the TcpStream in half to allow reading and writing data at the same time. This fixes an issue where you are unable to get chat messages until the client sends a packet to the server Fixed client id's by adding the id manager Added shout chat handling --- chat-service/src/chat_channels/guild_chat.rs | 26 +++-- chat-service/src/chat_channels/local_chat.rs | 14 ++- chat-service/src/chat_channels/shout_chat.rs | 12 +- chat-service/src/chat_service.rs | 19 ++- packet-service/src/connection_service.rs | 23 +++- packet-service/src/connection_state.rs | 11 ++ packet-service/src/handlers/auth.rs | 117 +++++++++++++------ packet-service/src/handlers/character.rs | 56 +++++---- packet-service/src/handlers/chat.rs | 112 ++++++++++++++---- packet-service/src/handlers/chat_client.rs | 7 +- packet-service/src/handlers/world.rs | 102 ++++++++++++++-- packet-service/src/id_manager.rs | 61 ++++++++++ packet-service/src/lib.rs | 1 + packet-service/src/main.rs | 11 +- packet-service/src/packet.rs | 4 +- packet-service/src/router.rs | 60 ++++------ proto/chat.proto | 1 + 17 files changed, 480 insertions(+), 157 deletions(-) create mode 100644 packet-service/src/id_manager.rs diff --git a/chat-service/src/chat_channels/guild_chat.rs b/chat-service/src/chat_channels/guild_chat.rs index 49332cc..84da883 100644 --- a/chat-service/src/chat_channels/guild_chat.rs +++ b/chat-service/src/chat_channels/guild_chat.rs @@ -8,15 +8,21 @@ pub struct GuildChat; impl ChatChannel for GuildChat { fn handle_message(&self, message: ChatMessage, sender_id: &str, clients: &Clients) { - // This is a placeholder. In a real implementation, verify - // guild membership by consulting your Character or Guild service. - let clients_lock = clients.lock().unwrap(); - for (id, tx) in clients_lock.iter() { - // For demonstration, send only to clients whose IDs contain - // "guild". Replace this logic with your actual membership check. - if id != sender_id && id.contains("guild") { - let _ = tx.try_send(message.clone()); - } - } + //TODO: Make sure the clients actually are apart of the same guild. + + let new_message = ChatMessage { + client_id: sender_id.to_string(), + r#type: message.r#type, + message: message.message, + target_id: message.target_id, + sender: message.sender, + }; + + // let clients_lock = clients.lock().unwrap(); + // for (id, tx) in clients_lock.iter() { + // if id != sender_id && id.contains("guild") { + // let _ = tx.try_send(new_message.clone()); + // } + // } } } \ No newline at end of file diff --git a/chat-service/src/chat_channels/local_chat.rs b/chat-service/src/chat_channels/local_chat.rs index 778091c..b6d92b8 100644 --- a/chat-service/src/chat_channels/local_chat.rs +++ b/chat-service/src/chat_channels/local_chat.rs @@ -9,14 +9,18 @@ pub struct LocalChat; impl ChatChannel for LocalChat { fn handle_message(&self, message: ChatMessage, sender_id: &str, clients: &Clients) { - // In a full implementation, you might query for nearby clients. - // For demo purposes, we simply broadcast to all clients except the sender. debug!("LocalChat::handle_message: {:?}", message); + let new_message = ChatMessage { + client_id: sender_id.to_string(), // Make sure the client isn't attempting bad things + r#type: message.r#type, + message: message.message, + target_id: message.target_id, + sender: message.sender, + }; + let clients_lock = clients.lock().unwrap(); for (id, tx) in clients_lock.iter() { - // if id != sender_id { - let _ = tx.try_send(message.clone()); - // } + let _ = tx.try_send(new_message.clone()); } } } \ No newline at end of file diff --git a/chat-service/src/chat_channels/shout_chat.rs b/chat-service/src/chat_channels/shout_chat.rs index 437e068..04b2165 100644 --- a/chat-service/src/chat_channels/shout_chat.rs +++ b/chat-service/src/chat_channels/shout_chat.rs @@ -8,13 +8,17 @@ pub struct ShoutChat; impl ChatChannel for ShoutChat { fn handle_message(&self, message: ChatMessage, sender_id: &str, clients: &Clients) { - // For demo purposes, we simply broadcast to all clients except the sender. // TODO: make sure the clients are on the same map + let new_message = ChatMessage { + client_id: sender_id.to_string(), + r#type: message.r#type, + message: message.message, + target_id: message.target_id, + sender: message.sender, + }; let clients_lock = clients.lock().unwrap(); for (id, tx) in clients_lock.iter() { - if id != sender_id { - let _ = tx.try_send(message.clone()); - } + let _ = tx.try_send(new_message.clone()); } } } \ No newline at end of file diff --git a/chat-service/src/chat_service.rs b/chat-service/src/chat_service.rs index 6e398d4..d6bc612 100644 --- a/chat-service/src/chat_service.rs +++ b/chat-service/src/chat_service.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::pin::Pin; use std::sync::{Arc, Mutex}; use tonic::{Request, Response, Status}; +use tonic::metadata::MetadataMap; use tracing::debug; pub mod common { @@ -37,6 +38,18 @@ impl MyChatService { } } +fn get_authenticated_id(metadata: &MetadataMap) -> Result { + if let Some(client_id_val) = metadata.get("x-client-id") { + // Convert the header to a string. + client_id_val + .to_str() + .map(ToString::to_string) + .map_err(|_| Status::unauthenticated("Invalid client ID header")) + } else { + Err(Status::unauthenticated("Missing client ID header")) + } +} + #[tonic::async_trait] impl ChatService for MyChatService { type ChatStreamStream = @@ -48,11 +61,9 @@ impl ChatService for MyChatService { ) -> Result, Status> { debug!("New chat client connected"); debug!("request: {:?}", request); - - let mut inbound = request.into_inner(); - // Create a new client ID. In production, use authenticated IDs. - let client_id = format!("client-{}", uuid::Uuid::new_v4()); + let client_id = get_authenticated_id(request.metadata())?; + let mut inbound = request.into_inner(); // Create a channel for sending outbound messages to this client. let (tx, rx) = tokio::sync::mpsc::channel(32); diff --git a/packet-service/src/connection_service.rs b/packet-service/src/connection_service.rs index 0956c6d..43cc6fb 100644 --- a/packet-service/src/connection_service.rs +++ b/packet-service/src/connection_service.rs @@ -1,23 +1,30 @@ use crate::connection_state::ConnectionState; +use crate::id_manager::IdManager; use dashmap::DashMap; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use uuid::Uuid; +use tokio::net::TcpStream; +use tokio::io::{WriteHalf}; #[derive(Clone, Debug)] pub struct ConnectionService { pub connections: Arc>, // Map connection ID to state + pub id_manager: Arc> } impl ConnectionService { pub fn new() -> Self { Self { connections: Arc::new(DashMap::new()), + id_manager: Arc::new(Mutex::new(IdManager::new())), } } - pub fn add_connection(&self) -> String { + pub fn add_connection(&self, writer: Arc>>) -> String { let connection_id = Uuid::new_v4().to_string(); - self.connections.insert(connection_id.clone(), ConnectionState::new()); + let mut connection_state = ConnectionState::new(); + connection_state.writer = Some(writer); + self.connections.insert(connection_id.clone(), connection_state); connection_id } @@ -35,4 +42,14 @@ impl ConnectionService { pub fn remove_connection(&self, connection_id: &str) { self.connections.remove(connection_id); } + + pub fn next_id(&self) -> u16 { + let mut manager = self.id_manager.lock().unwrap(); + manager.get_free_id() + } + + pub fn free_id(&self, id: u16) { + let mut manager = self.id_manager.lock().unwrap(); + manager.release_id(id); + } } diff --git a/packet-service/src/connection_state.rs b/packet-service/src/connection_state.rs index dd496cb..f7bd49c 100644 --- a/packet-service/src/connection_state.rs +++ b/packet-service/src/connection_state.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; use std::sync::Arc; use std::fmt; +use tokio::net::TcpStream; +use tokio::io::{WriteHalf}; use crate::handlers::chat_client::ChatClientHandler; @@ -9,9 +11,12 @@ pub struct ConnectionState { pub user_id: Option, pub session_id: Option, pub character_id: Option, + pub character_name: Option, pub character_list: Option>, pub additional_data: HashMap, // Flexible data storage + pub client_id: u16, pub chat_handler: Option>, + pub writer: Option>>>, } impl ConnectionState { @@ -20,9 +25,12 @@ impl ConnectionState { user_id: None, session_id: None, character_id: None, + character_name: None, character_list: None, additional_data: HashMap::new(), + client_id: 0, chat_handler: None, + writer: None, } } } @@ -33,9 +41,12 @@ impl fmt::Debug for ConnectionState { .field("user_id", &self.user_id) .field("session_id", &self.session_id) .field("character_id", &self.character_id) + .field("character_name", &self.character_name) .field("character_list", &self.character_list) .field("additional_data", &self.additional_data) + .field("client_id", &self.client_id) .field("chat_handler", &self.chat_handler.as_ref().map(|_| "")) + .field("writer", &self.writer.as_ref().map(|_| "")) .finish() } } \ No newline at end of file diff --git a/packet-service/src/handlers/auth.rs b/packet-service/src/handlers/auth.rs index b642798..9a1f6f3 100644 --- a/packet-service/src/handlers/auth.rs +++ b/packet-service/src/handlers/auth.rs @@ -20,7 +20,6 @@ use crate::handlers::chat::create_chat_client_handler; use crate::handlers::chat_client::ChatClientHandler; pub(crate) async fn handle_alive_req( - stream: Arc>, packet: Packet, auth_client: Arc>, connection_service: Arc, @@ -42,8 +41,9 @@ pub(crate) async fn handle_alive_req( } pub(crate) async fn handle_accept_req( - stream: Arc>, packet: Packet, + connection_service: Arc, + connection_id: String, ) -> Result<(), Box> { use crate::packets::srv_accept_reply::SrvAcceptReply; let data = SrvAcceptReply { @@ -52,13 +52,15 @@ pub(crate) async fn handle_accept_req( }; let response_packet = Packet::new(PacketType::PakssAcceptReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_join_server_req( - stream: Arc>, packet: Packet, auth_client: Arc>, connection_service: Arc, @@ -82,19 +84,26 @@ pub(crate) async fn handle_join_server_req( pay_flag: 0, }; let response_packet = Packet::new(PacketType::PakscJoinServerReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } return Err("Session not valid".into()); } + let client_id = state.client_id.clone(); let data = SrvJoinServerReply { result: srv_join_server_reply::Result::Ok, - id: 1, + id: client_id as u32, pay_flag: 0, }; let response_packet = Packet::new(PacketType::PakscJoinServerReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } else { Err("Unable to find connection state".into()) @@ -102,7 +111,6 @@ pub(crate) async fn handle_join_server_req( } pub(crate) async fn handle_logout_req( - stream: Arc>, packet: Packet, auth_client: Arc>, connection_service: Arc, @@ -116,9 +124,12 @@ pub(crate) async fn handle_logout_req( let data = SrvLogoutReply { wait_time: 1 }; let response_packet = Packet::new(PacketType::PakwcLogoutReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; - locked_stream.shutdown().await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + locked_stream.shutdown().await?; + } Ok(()) } else { Err("Unable to find connection state".into()) @@ -126,7 +137,6 @@ pub(crate) async fn handle_logout_req( } pub(crate) async fn handle_login_req( - stream: Arc>, packet: Packet, auth_client: Arc>, connection_service: Arc, @@ -152,14 +162,20 @@ pub(crate) async fn handle_login_req( servers_info: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } else { debug!("Successfully logged in"); + let mut client_id = 0; if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { state.user_id = Some(response.user_id); state.session_id = Some(response.session_id.clone()); + client_id = connection_service.next_id(); + state.client_id = client_id; } let chat_url = format!( @@ -171,10 +187,13 @@ pub(crate) async fn handle_login_req( .unwrap() ); - let handler = ChatClientHandler::new(chat_url, connection_id.clone(), response.session_id.clone()).await?; + let handler = ChatClientHandler::new(chat_url, client_id.to_string(), response.session_id.clone()).await?; let chat_handler = Arc::new(handler); - create_chat_client_handler(stream.clone(), chat_handler.clone()).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + create_chat_client_handler(writer_clone, chat_handler.clone()).await?; + } if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { state.chat_handler = Some(chat_handler); @@ -216,8 +235,11 @@ pub(crate) async fn handle_login_req( servers_info: server_info, }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } } Err(err) => { @@ -229,8 +251,11 @@ pub(crate) async fn handle_login_req( servers_info: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } return Ok(()); } } @@ -249,8 +274,11 @@ pub(crate) async fn handle_login_req( servers_info: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } Code::Unavailable => { warn!("Login failed: Service is unavailable"); @@ -261,8 +289,11 @@ pub(crate) async fn handle_login_req( servers_info: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } _ => { error!("Unexpected error: {}", tonic_status.message()); @@ -273,8 +304,11 @@ pub(crate) async fn handle_login_req( servers_info: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } } } @@ -285,7 +319,6 @@ pub(crate) async fn handle_login_req( } pub(crate) async fn handle_server_select_req( - stream: Arc>, packet: Packet, connection_service: Arc, connection_id: String, @@ -313,14 +346,18 @@ pub(crate) async fn handle_server_select_req( }; let response_packet = Packet::new(PacketType::PaklcSrvSelectReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_channel_list_req( - stream: Arc>, packet: Packet, + connection_service: Arc, + connection_id: String, ) -> Result<(), Box> { use crate::packets::cli_channel_list_req::CliChannelListReq; use crate::packets::srv_channel_list_reply::{ChannelInfo, SrvChannelListReply}; @@ -356,8 +393,11 @@ pub(crate) async fn handle_channel_list_req( channels: channel_info, }; let response_packet = Packet::new(PacketType::PaklcChannelListReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } } } Err(err) => { @@ -366,8 +406,11 @@ pub(crate) async fn handle_channel_list_req( channels: Vec::new(), }; let response_packet = Packet::new(PacketType::PaklcChannelListReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } return Ok(()); } } diff --git a/packet-service/src/handlers/character.rs b/packet-service/src/handlers/character.rs index 6658781..90fe177 100644 --- a/packet-service/src/handlers/character.rs +++ b/packet-service/src/handlers/character.rs @@ -68,7 +68,6 @@ pub(crate) fn convert_type_to_body_part(slot: i32) -> ItemType { } pub(crate) async fn handle_char_list_req( - stream: Arc>, packet: Packet, character_client: Arc>, connection_service: Arc, @@ -130,14 +129,16 @@ pub(crate) async fn handle_char_list_req( let data = SrvCharListReply { characters }; let response_packet = Packet::new(PacketType::PakccCharListReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_create_char_req( - stream: Arc>, packet: Packet, character_client: Arc>, connection_service: Arc, @@ -179,14 +180,16 @@ pub(crate) async fn handle_create_char_req( let data = SrvCreateCharReply { result, platininum: 0 }; let response_packet = Packet::new(PacketType::PakccCreateCharReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_delete_char_req( - stream: Arc>, packet: Packet, character_client: Arc>, connection_service: Arc, @@ -222,14 +225,16 @@ pub(crate) async fn handle_delete_char_req( name: character_name, }; let response_packet = Packet::new(PacketType::PakccDeleteCharReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_select_char_req( - stream: Arc>, packet: Packet, character_client: Arc>, connection_service: Arc, @@ -260,8 +265,9 @@ pub(crate) async fn handle_select_char_req( ip: NullTerminatedString("".to_string()), }; let response_packet = Packet::new(PacketType::PakccSwitchServer, &data)?; - { - let mut locked_stream = stream.lock().await; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; send_packet(&mut locked_stream, &response_packet).await?; } @@ -283,7 +289,11 @@ pub(crate) async fn handle_select_char_req( core::array::from_fn(|i| EquippedItem::default()); let mut inventory: [srv_inventory_data::Item; (MAX_ITEMS as usize)] = core::array::from_fn(|i| srv_inventory_data::Item::default()); - + + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + state.character_name = Some(character.name.clone()); + } + // Build the character learned skill list let mut skill_list: [u16; (MAX_SKILL_COUNT as usize)] = [0u16; MAX_SKILL_COUNT as usize]; for index in 0..skills.len() { @@ -372,8 +382,9 @@ pub(crate) async fn handle_select_char_req( name, }; let response_packet = Packet::new(PacketType::PakwcSelectCharReply, &data)?; - { - let mut locked_stream = stream.lock().await; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; send_packet(&mut locked_stream, &response_packet).await?; } @@ -383,8 +394,9 @@ pub(crate) async fn handle_select_char_req( items: inventory, }; let response_packet = Packet::new(PacketType::PakwcInventoryData, &data)?; - { - let mut locked_stream = stream.lock().await; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; send_packet(&mut locked_stream, &response_packet).await?; } @@ -404,8 +416,9 @@ pub(crate) async fn handle_select_char_req( wishlist, }; let response_packet = Packet::new(PacketType::PakwcQuestData, &data)?; - { - let mut locked_stream = stream.lock().await; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; send_packet(&mut locked_stream, &response_packet).await?; } @@ -415,8 +428,9 @@ pub(crate) async fn handle_select_char_req( pay_flag: 2, }; let response_packet = Packet::new(PacketType::PakwcBillingMessage, &data)?; - { - let mut locked_stream = stream.lock().await; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; send_packet(&mut locked_stream, &response_packet).await?; } diff --git a/packet-service/src/handlers/chat.rs b/packet-service/src/handlers/chat.rs index 8a1ef64..5a39bd0 100644 --- a/packet-service/src/handlers/chat.rs +++ b/packet-service/src/handlers/chat.rs @@ -5,6 +5,7 @@ use crate::packet_type::PacketType; use chrono::{Local, Timelike}; use std::error::Error; use std::sync::Arc; +use tokio::io::WriteHalf; use tokio::net::TcpStream; use tokio::sync::Mutex; use tonic::transport::Channel; @@ -15,7 +16,7 @@ use crate::handlers::chat_client::chat::{ChatMessage, MessageType}; use crate::handlers::chat_client::ChatClientHandler; pub async fn create_chat_client_handler( - stream_for_task: Arc>, + stream_for_task: Arc>>, task_chat_handler: Arc, ) -> Result<(), Box> { use crate::packets::srv_normal_chat::SrvNormalChat; @@ -31,21 +32,20 @@ pub async fn create_chat_client_handler( let mut rx = task_chat_handler.inbound_rx.lock().await; while let Some(chat_msg) = rx.recv().await { debug!("Packet-Service received chat message: {} (client_id: {}, type {})", chat_msg.message, chat_msg.client_id, chat_msg.r#type); - - debug!("Locking stream"); - let mut locked_stream = stream_for_task.lock().await; - debug!("Locked stream"); match chat_msg.r#type { 1 => { // Normal Chat let data = SrvNormalChat { - char_id: chat_msg.client_id.parse().unwrap_or(696), + char_id: chat_msg.client_id.parse().unwrap(), message: NullTerminatedString(chat_msg.message), }; // Send the packet to the client let response_packet = Packet::new(PacketType::PakwcNormalChat, &data); debug!("Attempting to send normal chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await { error!("unable to send normal chat: {:?}", e); @@ -54,11 +54,14 @@ pub async fn create_chat_client_handler( 2 => { // Shout Chat let data = SrvShoutChat { - sender: Default::default(), + sender: NullTerminatedString(chat_msg.sender), message: NullTerminatedString(chat_msg.message), }; let response_packet = Packet::new(PacketType::PakwcShoutChat, &data); debug!("Attempting to send shout chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await { error!("unable to send shout chat: {:?}", e); @@ -66,25 +69,80 @@ pub async fn create_chat_client_handler( } 3 => { // Party Chat + let data = SrvPartyChat { + char_id: chat_msg.client_id.parse().unwrap(), + message: NullTerminatedString(chat_msg.message), + }; + let response_packet = Packet::new(PacketType::PakwcPartyChat, &data); + debug!("Attempting to send party chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); + if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await + { + error!("unable to send party chat: {:?}", e); + } } 4 => { // Whisper Chat + let data = SrvWhisperChat { + sender: NullTerminatedString(chat_msg.sender), + message: NullTerminatedString(chat_msg.message), + }; + let response_packet = Packet::new(PacketType::PakwcWhisperChat, &data); + debug!("Attempting to send whisper chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); + if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await + { + error!("unable to send whisper chat: {:?}", e); + } } 5 => { // Clan Chat + let data = SrvClanChat { + sender: NullTerminatedString(chat_msg.sender), + message: NullTerminatedString(chat_msg.message), + }; + let response_packet = Packet::new(PacketType::PakwcClanChat, &data); + debug!("Attempting to send clan chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); + if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await + { + error!("unable to send clan chat: {:?}", e); + } } 6 => { // Allied Chat + let data = SrvAlliedChat { + team: 0, + message: NullTerminatedString(chat_msg.message), + }; + let response_packet = Packet::new(PacketType::PakwcAlliedChat, &data); + debug!("Attempting to send allied chat to client"); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); + if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await + { + error!("unable to send allied chat: {:?}", e); + } } _ => { // Normal Chat let data = SrvNormalChat { - char_id: 0, + char_id: chat_msg.client_id.parse().unwrap(), message: NullTerminatedString(chat_msg.message), }; // Send the packet to the client let response_packet = Packet::new(PacketType::PakwcNormalChat, &data); + debug!("Locking stream"); + let mut locked_stream = stream_for_task.lock().await; + debug!("Locked stream"); if let Err(e) = send_packet(&mut locked_stream, &response_packet.unwrap()).await { error!("unable to send normal chat: {:?}", e); @@ -101,7 +159,6 @@ pub async fn create_chat_client_handler( } pub(crate) async fn handle_normal_chat( - stream: Arc>, packet: Packet, connection_service: Arc, connection_id: String, @@ -114,23 +171,36 @@ pub(crate) async fn handle_normal_chat( if let Some(mut state) = connection_service.get_connection(&connection_id) { let user_id = state.user_id.clone().expect("Missing user id in connection state"); let message = ChatMessage { - client_id: crate::handlers::character::string_to_u32(&user_id).to_string(), + client_id: state.client_id.clone().to_string(), r#type: MessageType::Normal as i32, message: request.message.clone().0, target_id: "".to_string(), + sender: state.character_name.clone().unwrap(), + }; + state.chat_handler.unwrap().send_message(message).await; + } + Ok(()) +} + +pub(crate) async fn handle_shout_chat( + packet: Packet, + connection_service: Arc, + connection_id: String, +) -> Result<(), Box> { + use crate::packets::cli_shout_chat::*; + use crate::packets::srv_shout_chat::*; + let request = CliShoutChat::decode(packet.payload.as_slice())?; + debug!("{:?}", request); + + if let Some(mut state) = connection_service.get_connection(&connection_id) { + let message = ChatMessage { + client_id: state.client_id.clone().to_string(), + r#type: MessageType::Shout as i32, + message: request.message.clone().0, + target_id: "".to_string(), + sender: state.character_name.clone().unwrap(), }; state.chat_handler.unwrap().send_message(message).await; } - - - // We're not sending here because we should get a message back from the chat service - // let data = SrvNormalChat { - // char_id: 0, - // message: request.message, - // }; - // let response_packet = Packet::new(PacketType::PakwcNormalChat, &data)?; - // let mut locked_stream = stream.lock().await; - // send_packet(&mut locked_stream, &response_packet).await?; - Ok(()) } diff --git a/packet-service/src/handlers/chat_client.rs b/packet-service/src/handlers/chat_client.rs index 8ec123f..cbc0f59 100644 --- a/packet-service/src/handlers/chat_client.rs +++ b/packet-service/src/handlers/chat_client.rs @@ -3,6 +3,7 @@ use futures::StreamExt; use tokio::sync::{mpsc, Mutex}; use tokio_stream::wrappers::ReceiverStream; use std::error::Error; +use tracing::{debug, error}; pub mod chat { tonic::include_proto!("chat"); @@ -61,17 +62,17 @@ impl ChatClientHandler { // You might translate or process the chat_msg here, // then forward it to your packet-service logic. if let Err(e) = in_tx.send(chat_msg).await { - eprintln!("Failed to forward chat message: {:?}", e); + error!("Failed to forward chat message: {:?}", e); break; } } Err(e) => { - eprintln!("Error receiving chat stream message: {:?}", e); + error!("Error receiving chat stream message: {:?}", e); break; } } } - println!("Chat inbound stream closed"); + debug!("Chat inbound stream closed"); }); Ok(Self { diff --git a/packet-service/src/handlers/world.rs b/packet-service/src/handlers/world.rs index 72db0b0..8482285 100644 --- a/packet-service/src/handlers/world.rs +++ b/packet-service/src/handlers/world.rs @@ -17,7 +17,6 @@ fn distance(x1: f64, y1: f64, x2: f64, y2: f64) -> u16 { } pub(crate) async fn handle_change_map_req( - stream: Arc>, packet: Packet, character_client: Arc>, connection_service: Arc, @@ -30,6 +29,7 @@ pub(crate) async fn handle_change_map_req( let mut user_id = "".to_string(); let mut char_id = 0; + let mut client_id = 0; let mut character_id_list: Vec = Vec::new(); let session_id; if let Some(mut state) = connection_service.get_connection(&connection_id) { @@ -37,6 +37,7 @@ pub(crate) async fn handle_change_map_req( session_id = state.session_id.expect("Missing session id in connection state"); char_id = state.character_id.expect("Missing character id in connection state"); character_id_list = state.character_list.clone().expect("Missing character id list"); + client_id = state.client_id; } let mut character_client = character_client.lock().await; @@ -51,7 +52,7 @@ pub(crate) async fn handle_change_map_req( let time_as_u16 = (now.hour() * 100 + now.minute()) as u16; let data = SrvChangeMapReply { - object_index: character_id_list[char_id as usize] as u16, + object_index: client_id, hp: stats.hp as u16, mp: stats.mp as u16, xp: stats.xp as u16, @@ -66,14 +67,16 @@ pub(crate) async fn handle_change_map_req( team_number: 10, }; let response_packet = Packet::new(PacketType::PakwcChangeMapReply, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } pub(crate) async fn handle_mouse_cmd_req( - stream: Arc>, packet: Packet, connection_service: Arc, connection_id: String, @@ -84,14 +87,16 @@ pub(crate) async fn handle_mouse_cmd_req( debug!("{:?}", request); let mut char_id = 0; + let mut client_id = 0; let mut character_id_list: Vec = Vec::new(); if let Some(mut state) = connection_service.get_connection(&connection_id) { char_id = state.character_id.expect("Missing character id in connection state"); character_id_list = state.character_list.clone().expect("Missing character id list"); + client_id = state.client_id; } let data = SrvMouseCmd { - id: character_id_list[char_id as usize] as u16, + id: client_id, target_id: request.target_id, distance: distance(520000 as f64, 520000 as f64, request.x as f64, request.y as f64), x: request.x, @@ -99,7 +104,88 @@ pub(crate) async fn handle_mouse_cmd_req( z: request.z, }; let response_packet = Packet::new(PacketType::PakwcMouseCmd, &data)?; - let mut locked_stream = stream.lock().await; - send_packet(&mut locked_stream, &response_packet).await?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } Ok(()) } + +pub(crate) async fn handle_togggle_move_req( + packet: Packet, + connection_service: Arc, + connection_id: String, +) -> Result<(), Box> { + use crate::packets::cli_toggle_move::*; + use crate::packets::srv_toggle_move::*; + let request = CliToggleMove::decode(packet.payload.as_slice())?; + debug!("{:?}", request); + + let mut client_id = 0; + if let Some(mut state) = connection_service.get_connection(&connection_id) { + client_id = state.client_id; + } + let mut toggle_type = 0;; + { + use crate::packets::cli_toggle_move::ToggleMove; + match request.type_ { + ToggleMove::Run => { toggle_type = 2; } + ToggleMove::Sit => { toggle_type = 8; } + ToggleMove::Drive => { toggle_type = 9; } + } + } + + use crate::packets::srv_toggle_move::ToggleMove; + let mut final_type = ToggleMove::Run; + { + match toggle_type { + 0 => { final_type = ToggleMove::Run; } + 1 => { final_type = ToggleMove::Sit; } + 2 => { final_type = ToggleMove::Drive; } + _ => { final_type = ToggleMove::Run; } + } + } + + let data = SrvToggleMove { + object_id: client_id, + type_: final_type, + run_speed: 0, + }; + let response_packet = Packet::new(PacketType::PakwcToggleMove, &data)?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } + Ok(()) +} + +pub(crate) async fn handle_set_animation_req( + packet: Packet, + connection_service: Arc, + connection_id: String, +) -> Result<(), Box> { + use crate::packets::cli_set_animation::*; + use crate::packets::srv_set_animation::*; + let request = CliSetAnimation::decode(packet.payload.as_slice())?; + debug!("{:?}", request); + + let mut client_id = 0; + if let Some(mut state) = connection_service.get_connection(&connection_id) { + client_id = state.client_id; + } + + let data = SrvSetAnimation { + id: request.id, + value: request.value, + object_id: client_id, + }; + let response_packet = Packet::new(PacketType::PacwcSetAnimation, &data)?; + if let Some(mut state) = connection_service.get_connection_mut(&connection_id) { + let writer_clone = state.writer.clone().unwrap(); + let mut locked_stream = writer_clone.lock().await; + send_packet(&mut locked_stream, &response_packet).await?; + } + Ok(()) +} \ No newline at end of file diff --git a/packet-service/src/id_manager.rs b/packet-service/src/id_manager.rs new file mode 100644 index 0000000..2283da9 --- /dev/null +++ b/packet-service/src/id_manager.rs @@ -0,0 +1,61 @@ +use std::collections::HashSet; + +#[derive(Clone, Debug)] +pub struct IdManager { + free_ids: HashSet, + max_id: u16, // the first ID is 1 +} + +impl IdManager { + /// Creates a new IdManager with no free IDs and starting ID of 1. + pub fn new() -> Self { + Self { + free_ids: HashSet::new(), + max_id: 1, + } + } + + /// Retrieves an available ID. + /// + /// If any are available in the free_ids set, returns one of them. + /// Otherwise, returns a fresh ID and increments max_id. + pub fn get_free_id(&mut self) -> u16 { + if let Some(&id) = self.free_ids.iter().next() { + self.free_ids.remove(&id); + id + } else { + let id = self.max_id; + self.max_id += 1; + id + } + } + + /// Releases an ID, making it available for reuse. + pub fn release_id(&mut self, id: u16) { + self.free_ids.insert(id); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_id_manager() { + let mut manager = IdManager::new(); + + let id1 = manager.get_free_id(); + let id2 = manager.get_free_id(); + assert_eq!(id1, 1); + assert_eq!(id2, 2); + + // Release id1 and then get a free id which should return id1 + manager.release_id(id1); + let id3 = manager.get_free_id(); + assert_eq!(id3, id1); + + // Next free id should be id3 (old id2 was already used) + let id4 = manager.get_free_id(); + assert_eq!(id4, 3); + } +} \ No newline at end of file diff --git a/packet-service/src/lib.rs b/packet-service/src/lib.rs index be0a3e1..b1fccb6 100644 --- a/packet-service/src/lib.rs +++ b/packet-service/src/lib.rs @@ -5,6 +5,7 @@ pub mod connection_state; pub mod metrics; pub mod packet; pub mod packet_type; +pub mod id_manager; pub mod handlers { pub mod chat_client; } diff --git a/packet-service/src/main.rs b/packet-service/src/main.rs index 9dc187d..32e78cd 100644 --- a/packet-service/src/main.rs +++ b/packet-service/src/main.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use tokio::io::AsyncReadExt; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::{Mutex, Semaphore}; -use tokio::{select, signal}; +use tokio::{io, select, signal}; use tracing::Level; use tracing::{debug, error, info, warn}; use tracing_subscriber::EnvFilter; @@ -40,6 +40,7 @@ mod packets; mod router; mod types; mod interceptors; +mod id_manager; pub mod common { tonic::include_proto!("common"); @@ -111,14 +112,16 @@ async fn main() -> Result<(), Box> { let pool = buffer_pool.clone(); let permit = semaphore.clone().acquire_owned().await.unwrap(); - let stream = Arc::new(Mutex::new(socket)); + let peer_addr = socket.peer_addr().unwrap(); + let (mut reader, writer) = io::split(socket); + let writer = Arc::new(tokio::sync::Mutex::new(writer)); // Spawn a new task for each connection tokio::spawn(async move { let _permit = permit; - let connection_id = packet_router.connection_service.add_connection(); + let connection_id = packet_router.connection_service.add_connection(writer); if let Err(e) = packet_router - .handle_connection(stream, pool, connection_id.clone()) + .handle_connection(reader, pool, connection_id.clone(), peer_addr.to_string()) .await { error!("Error handling connection: {}", e); diff --git a/packet-service/src/packet.rs b/packet-service/src/packet.rs index 5b78a32..11bfa60 100644 --- a/packet-service/src/packet.rs +++ b/packet-service/src/packet.rs @@ -2,7 +2,7 @@ use crate::metrics::PACKETS_SENT; use crate::packet_type::PacketType; use bincode::{Decode, Encode}; use std::error::Error; -use tokio::io::AsyncWriteExt; +use tokio::io::{AsyncWriteExt, WriteHalf}; use tokio::net::TcpStream; use tracing::{debug, error}; @@ -110,7 +110,7 @@ impl Packet { } } -pub async fn send_packet(stream: &mut TcpStream, packet: &Packet) -> Result<(), std::io::Error> { +pub async fn send_packet(stream: &mut WriteHalf, packet: &Packet) -> Result<(), std::io::Error> { let data = packet.to_raw(); debug!("Sending '{:#X}' bytes of data. {:?}", data.len(), data); PACKETS_SENT.inc(); diff --git a/packet-service/src/router.rs b/packet-service/src/router.rs index 4e16059..525d451 100644 --- a/packet-service/src/router.rs +++ b/packet-service/src/router.rs @@ -8,7 +8,7 @@ use crate::packet::Packet; use crate::packet_type::PacketType; use std::error::Error; use std::sync::Arc; -use tokio::io::AsyncReadExt; +use tokio::io::{AsyncReadExt, ReadHalf}; use tokio::net::TcpStream; use tokio::sync::Mutex; use tracing::{debug, warn}; @@ -23,30 +23,20 @@ pub struct PacketRouter { impl PacketRouter { pub async fn handle_connection( &self, - stream: Arc>, + mut stream: ReadHalf, pool: Arc, connection_id: String, + peer_addr: String, ) -> Result<(), Box> { ACTIVE_CONNECTIONS.inc(); while let Some(mut buffer) = pool.acquire().await { // Read data into the buffer let packet_size: usize; { - let mut locked_stream = stream.lock().await; - locked_stream.read_exact(&mut buffer[..6]).await?; - // let mut header_handle = locked_stream.take(6); - // let n = header_handle.read(&mut buffer).await?; - // if n == 0 { - // break; // Connection closed - // } + stream.read_exact(&mut buffer[..6]).await?; packet_size = u16::from_le_bytes(buffer[0..2].try_into()?) as usize; if packet_size > 6 { - locked_stream.read_exact(&mut buffer[6..packet_size]).await?; - // let mut body_handle = locked_stream.take((packet_size - 6) as u64); - // let n = body_handle.read(&mut buffer[6..]).await?; - // if n == 0 { - // break; // Connection closed - // } + stream.read_exact(&mut buffer[6..packet_size]).await?; } } @@ -57,8 +47,7 @@ impl PacketRouter { match Packet::from_raw(&buffer[..packet_size]) { Ok(packet) => { debug!("Parsed Packet: {:?}", packet); - // Handle the parsed packet (route it, process it, etc.) - self.route_packet(stream.clone(), packet, connection_id.clone()).await?; + self.route_packet(packet, connection_id.clone()).await?; } Err(e) => warn!("Failed to parse packet: {}", e), } @@ -73,8 +62,7 @@ impl PacketRouter { let mut auth_client = self.auth_client.lock().await; auth_client.logout(&session_id).await?; } else { - let mut locked_stream = stream.lock().await; - warn!("No session found for {}", locked_stream.peer_addr()?); + warn!("No session found for {}", peer_addr); } } ACTIVE_CONNECTIONS.dec(); @@ -84,34 +72,36 @@ impl PacketRouter { #[rustfmt::skip] pub async fn route_packet( &self, - stream: Arc>, packet: Packet, connection_id: String, ) -> Result<(), Box> { debug!("Routing packet: {:?}", packet); match packet.packet_type { // Generic Server Packets - PacketType::PakcsAlive => auth::handle_alive_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsAcceptReq => auth::handle_accept_req(stream, packet).await, - PacketType::PakcsJoinServerTokenReq => auth::handle_join_server_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsAlive => auth::handle_alive_req( packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsAcceptReq => auth::handle_accept_req(packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsJoinServerTokenReq => auth::handle_join_server_req(packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, // Login Packets - PacketType::PakcsLoginTokenReq => auth::handle_login_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsLogoutReq => auth::handle_logout_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsSrvSelectReq => auth::handle_server_select_req(stream, packet, self.connection_service.clone(), connection_id).await, - PacketType::PakcsChannelListReq => auth::handle_channel_list_req(stream, packet).await, + PacketType::PakcsLoginTokenReq => auth::handle_login_req(packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsLogoutReq => auth::handle_logout_req(packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsSrvSelectReq => auth::handle_server_select_req(packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsChannelListReq => auth::handle_channel_list_req(packet, self.connection_service.clone(), connection_id).await, // Character Packets - PacketType::PakcsCharListReq => character::handle_char_list_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsCreateCharReq => character::handle_create_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsDeleteCharReq => character::handle_delete_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsSelectCharReq => character::handle_select_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsCharListReq => character::handle_char_list_req(packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsCreateCharReq => character::handle_create_char_req(packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsDeleteCharReq => character::handle_delete_char_req(packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsSelectCharReq => character::handle_select_char_req(packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, // World Packets - PacketType::PakcsChangeMapReq => world::handle_change_map_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, - PacketType::PakcsMouseCmd => world::handle_mouse_cmd_req(stream, packet, self.connection_service.clone(), connection_id).await, - + PacketType::PakcsChangeMapReq => world::handle_change_map_req(packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await, + PacketType::PakcsMouseCmd => world::handle_mouse_cmd_req(packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsToggleMove => world::handle_togggle_move_req(packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsSetAnimation => world::handle_set_animation_req(packet, self.connection_service.clone(), connection_id).await, + // Chat Packets - PacketType::PakcsNormalChat => chat::handle_normal_chat(stream, packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsNormalChat => chat::handle_normal_chat(packet, self.connection_service.clone(), connection_id).await, + PacketType::PakcsShoutChat => chat::handle_shout_chat(packet, self.connection_service.clone(), connection_id).await, // 1 => chat::handle_chat(packet).await?, // 2 => movement::handle_movement(packet).await?, _ => { diff --git a/proto/chat.proto b/proto/chat.proto index c2bc00b..d73dd8c 100644 --- a/proto/chat.proto +++ b/proto/chat.proto @@ -23,4 +23,5 @@ message ChatMessage { MessageType type = 2; string message = 3; string target_id = 4; + string sender = 5; }