From 4b9fda1f847d0b1fdcaf7d1d3299604ae8967fa4 Mon Sep 17 00:00:00 2001 From: Nobody Date: Sun, 3 Oct 2021 00:17:33 +0500 Subject: [PATCH] Login success! --- Cargo.toml | 2 + build.rs | 54 +++++- src/main.rs | 4 + src/server/auth_manager.rs | 20 +++ src/server/client_connection.rs | 18 +- src/server/game_server.rs | 18 +- src/server/game_world.rs | 287 ++++++++++++++++++++++++++++++++ src/server/ipc_message.rs | 28 +++- src/server/mod.rs | 4 + src/server/network_server.rs | 39 ++++- 10 files changed, 445 insertions(+), 29 deletions(-) create mode 100644 src/server/auth_manager.rs create mode 100644 src/server/game_world.rs diff --git a/Cargo.toml b/Cargo.toml index 1c1a687..c4105ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,8 @@ kcp = { path = "../kcp" } mhycrypt = { path = "../mhycrypt" } prost = "0.8" bytes = "1.1.0" +num-traits = "0.2" +num-derive = "0.3" [build-dependencies] prost-build = { version = "0.8.0" } diff --git a/build.rs b/build.rs index dc269da..ca8daeb 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,55 @@ use std::io::Result; + fn main() -> Result<()> { - prost_build::compile_protos(&["protobuf/packet_header.proto"], &["protobuf/"])?; - Ok(()) + let proto_dir = "protobuf"; + + let protos = vec![ + "packet_header", + + "GetPlayerTokenReq", + "GetPlayerTokenRsp", + "PlayerLoginReq", + "OpenStateUpdateNotify", + "StoreWeightLimitNotify", + "PlayerStoreNotify", + "AvatarDataNotify", + "PlayerEnterSceneNotify", + "PlayerLoginRsp", + "GetPlayerSocialDetailReq", + "GetPlayerSocialDetailRsp", + "EnterSceneReadyReq", + "EnterSceneReadyRsp", + "SceneInitFinishReq", + "EnterScenePeerNotify", + "WorldDataNotify", + "WorldPlayerInfoNotify", + "ScenePlayerInfoNotify", + "PlayerEnterSceneInfoNotify", + "PlayerGameTimeNotify", + "SceneTimeNotify", + "SceneDataNotify", + "HostPlayerNotify", + "SceneTeamUpdateNotify", + "SceneInitFinishRsp", + "EnterSceneDoneReq", + "SceneEntityAppearNotify", + "EnterSceneDoneRsp", + "PostEnterSceneReq", + "PostEnterSceneRsp", + + "WorldPlayerRTTNotify", + "PingReq", + "PingRsp", + "PlayerDataNotify", + + ]; + + let protos: Vec = protos.iter().map(|&x| format!("{}/{}.proto", proto_dir, x)).collect(); + + let ret = prost_build::compile_protos(&protos, &[format!("{}/", proto_dir)]); + + match ret { + Ok(_) => return Ok(()), + Err(e) => panic!("{}", e), + } } diff --git a/src/main.rs b/src/main.rs index 866f8cf..9144707 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,12 @@ +#[macro_use] +extern crate num_derive; + mod server; mod utils; pub mod proto { include!(concat!(env!("OUT_DIR"), "/proto.rs")); + include!(concat!("..", "/gen", "/packet_id.rs")); } use server::NetworkServer; diff --git a/src/server/auth_manager.rs b/src/server/auth_manager.rs new file mode 100644 index 0000000..b5d9b96 --- /dev/null +++ b/src/server/auth_manager.rs @@ -0,0 +1,20 @@ +use std::sync::mpsc; + +use crate::server::IpcMessage; + +pub struct AuthManager { + packets_to_send_tx: mpsc::Sender, +} + +impl AuthManager { + pub fn new(packets_to_send_tx: mpsc::Sender) -> AuthManager { + let am = AuthManager { + packets_to_send_tx: packets_to_send_tx, + }; + + return am; + } + + pub fn process_packet(&mut self, conv: u32, packet_id: u16, metadata: Vec, data: Vec) { + } +} diff --git a/src/server/client_connection.rs b/src/server/client_connection.rs index 2e7c835..8410cd9 100644 --- a/src/server/client_connection.rs +++ b/src/server/client_connection.rs @@ -18,6 +18,7 @@ pub struct ClientConnection { ikcp: Kcp, established_time: SystemTime, key: [u8; 0x1000], + pending_seed: Option, } pub struct Source @@ -49,6 +50,7 @@ impl ClientConnection { ikcp: Kcp::new(conv, token, s), established_time: SystemTime::now(), key: ClientConnection::read_key("master").try_into().expect("Incorrect master key"), + pending_seed: None, }; } @@ -57,6 +59,14 @@ impl ClientConnection { } pub fn process_udp_packet(&mut self, data: &[u8]) -> Vec> { + match self.pending_seed { + None => {}, + Some(seed) => { + mhycrypt::mhy_generate_key(&mut self.key, seed, false); + self.pending_seed = None; + }, + } + let mut packets: Vec> = Vec::new(); self.ikcp.input(data).unwrap(); self.ikcp.update(self.elapsed_time_millis()).unwrap(); @@ -77,12 +87,12 @@ impl ClientConnection { } pub fn update_key(&mut self, seed: u64) { - mhycrypt::mhy_generate_key(&mut self.key, seed, false); + self.pending_seed = Some(seed); } fn read_key(key_name: &str) -> Vec { - let filename = format!("{}/{}.key", "keys", key_name); - let mut f = fs::File::open(&filename).expect("no file found"); + let filename = format!("./{}/{}.key", "keys", key_name); + let mut f = fs::File::open(&filename).expect(&format!("File '{}' not found", filename)); let metadata = fs::metadata(&filename).expect("unable to read metadata"); let mut buffer = vec![0; metadata.len() as usize]; f.read(&mut buffer).expect("buffer overflow"); @@ -97,5 +107,7 @@ impl ClientConnection { let mut buf = data.to_owned(); mhycrypt::mhy_xor(&mut buf, &self.key); self.ikcp.send(&buf).expect("Failed to send data!"); + self.ikcp.flush().unwrap(); + self.ikcp.update(self.elapsed_time_millis()).unwrap(); } } diff --git a/src/server/game_server.rs b/src/server/game_server.rs index e352cd4..9d67c17 100644 --- a/src/server/game_server.rs +++ b/src/server/game_server.rs @@ -3,25 +3,9 @@ use std::thread; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; +use crate::server::GameWorld; use crate::server::IpcMessage; -pub struct GameWorld { - packets_to_send_tx: mpsc::Sender, -} - -impl GameWorld { - pub fn new(packets_to_send_tx: mpsc::Sender) -> GameWorld { - let gm = GameWorld { - packets_to_send_tx: packets_to_send_tx, - }; - - return gm; - } - - pub fn process_packet(&mut self, conv: u32, packet_id: u16, metadata: Vec, data: Vec) { - } -} - pub struct GameServer { packets_to_process_rx: mpsc::Receiver, packets_to_send_tx: mpsc::Sender, diff --git a/src/server/game_world.rs b/src/server/game_world.rs new file mode 100644 index 0000000..1612a6e --- /dev/null +++ b/src/server/game_world.rs @@ -0,0 +1,287 @@ +use std::sync::mpsc; +use std::io::Cursor; +use std::collections::HashMap; + +use prost::Message; + +use crate::proto; + +use crate::server::IpcMessage; + +pub type PacketCallback = fn(&mut GameWorld, u32, &proto::PacketHead, Vec) -> (); + +macro_rules! register_callback { + ($hashmap:ident, $req:ident, $rsp:ident, $handler:ident) => { + $hashmap.insert(proto::PacketId::$req, |slef: &mut GameWorld, conv: u32, metadata: &proto::PacketHead, data: Vec| { + let req = proto::$req::decode(&mut Cursor::new(data)).unwrap(); + let mut rsp = proto::$rsp::default(); + + slef.$handler(conv, &metadata, &req, &mut rsp); + + let message = IpcMessage::new_from_proto(conv, proto::PacketId::$rsp, metadata, &rsp); + slef.packets_to_send_tx.send(message).unwrap(); + }); + }; + + ($hashmap:ident, $notify:ident, $handler:ident) => { + $hashmap.insert(proto::PacketId::$notify, |slef: &mut GameWorld, conv: u32, metadata: &proto::PacketHead, data: Vec| { + let notify = proto::$req::decode(&mut Cursor::new(data)).unwrap(); + + slef.$handler(conv, &metadata, ¬ify); + }); + }; +} + +pub struct GameWorld { + packets_to_send_tx: mpsc::Sender, + callbacks: HashMap, +} + +impl GameWorld { + pub fn new(packets_to_send_tx: mpsc::Sender) -> GameWorld { + let mut callbacks: HashMap = HashMap::new(); + + register_callback!(callbacks, PingReq, PingRsp, process_ping); + register_callback!(callbacks, GetPlayerTokenReq, GetPlayerTokenRsp, process_get_token); + register_callback!(callbacks, PlayerLoginReq, PlayerLoginRsp, process_login_req); + register_callback!(callbacks, GetPlayerSocialDetailReq, GetPlayerSocialDetailRsp, process_social_details_req); + register_callback!(callbacks, EnterSceneReadyReq, EnterSceneReadyRsp, process_enter_ready); + register_callback!(callbacks, SceneInitFinishReq, SceneInitFinishRsp, process_scene_init_finish); + register_callback!(callbacks, EnterSceneDoneReq, EnterSceneDoneRsp, process_enter_done); + register_callback!(callbacks, PostEnterSceneReq, PostEnterSceneRsp, process_post_enter_scene); + + let gw = GameWorld { + packets_to_send_tx: packets_to_send_tx, + callbacks: callbacks, + }; + + return gw; + } + + pub fn process_packet(&mut self, conv: u32, packet_id: proto::PacketId, metadata: Vec, data: Vec) { + let callback = self.callbacks.get(&packet_id); + let metadata = proto::PacketHead::decode(&mut Cursor::new(metadata)).unwrap(); + + match callback { + Some(callback) => callback(self, conv, &metadata, data), + None => println!("Unhandled packet {:?}", packet_id), + } + } + + fn process_ping(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::PingReq, rsp: &mut proto::PingRsp) { + rsp.client_time = req.client_time; + } + + fn process_get_token(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::GetPlayerTokenReq, rsp: &mut proto::GetPlayerTokenRsp) { + let seed: u64 = 0x123456789ABCDEF0; // TODO: use real value! + rsp.account_type = req.account_type; + rsp.account_uid = req.account_uid.clone(); + rsp.token = format!("token-game-{}", req.account_uid); + rsp.secret_key_seed = seed; + rsp.uid = 0x1234; // TODO: use real value! + } + + fn process_login_req(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::PlayerLoginReq, rsp: &mut proto::PlayerLoginRsp) { + let mut data_notify = proto::PlayerDataNotify::default(); + data_notify.nick_name = "Fapper".to_string(); + data_notify.server_time = 1337000; + //prop_map = ; // TODO! + let message = IpcMessage::new_from_proto(conv, proto::PacketId::PlayerDataNotify, metadata, &data_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let open_state_notify = proto::OpenStateUpdateNotify::default(); + // TODO! + let message = IpcMessage::new_from_proto(conv, proto::PacketId::OpenStateUpdateNotify, metadata, &open_state_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let store_weight_notify = proto::StoreWeightLimitNotify::default(); + // TODO! + let message = IpcMessage::new_from_proto(conv, proto::PacketId::StoreWeightLimitNotify, metadata, &store_weight_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let player_store_notify = proto::PlayerStoreNotify::default(); + // TODO! + let message = IpcMessage::new_from_proto(conv, proto::PacketId::PlayerStoreNotify, metadata, &player_store_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let avatar_data_notify = proto::AvatarDataNotify::default(); + // TODO! + let message = IpcMessage::new_from_proto(conv, proto::PacketId::AvatarDataNotify, metadata, &avatar_data_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut enter_scene_notify = proto::PlayerEnterSceneNotify::default(); + // TODO! + let mut pos = proto::Vector::default(); + pos.x = -3400.0; + pos.y = 203.0; + pos.z = -3427.60; + enter_scene_notify.scene_id = 3; + enter_scene_notify.r#type = proto::EnterType::EnterSelf as i32; + enter_scene_notify.scene_begin_time = 1337000; + enter_scene_notify.pos = Some(pos); + enter_scene_notify.target_uid = 0x1234; + enter_scene_notify.world_level = 8; + enter_scene_notify.enter_scene_token = 1337; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::PlayerEnterSceneNotify, metadata, &enter_scene_notify); + self.packets_to_send_tx.send(message).unwrap(); + } + + fn process_social_details_req(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::GetPlayerSocialDetailReq, rsp: &mut proto::GetPlayerSocialDetailRsp) { + let mut details = proto::SocialDetail::default(); + + details.uid = req.uid; + details.nickname = "Fukker".to_string(); + details.level = 60; + details.signature = "Fuck you".to_string(); + //details.birthday = birthday; // TODO + details.world_level = 8; + details.online_state = proto::FriendOnlineState::FriendOnline as i32; + details.is_friend = true; + details.is_mp_mode_available = true; + details.name_card_id = 210051; + details.finish_achievement_num = 42; + details.tower_floor_index = 1; + details.tower_level_index = 1; + //details.show_avatar_info_list = ; // TODO + details.show_name_card_id_list = vec![210051]; + // Field 25! + + rsp.detail_data = Some(details); + } + + fn process_enter_ready(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::EnterSceneReadyReq, rsp: &mut proto::EnterSceneReadyRsp) { + rsp.enter_scene_token = req.enter_scene_token; + + let mut peer_notify = proto::EnterScenePeerNotify::default(); + peer_notify.dest_scene_id = 3; + peer_notify.peer_id = 1; + peer_notify.host_peer_id = 1; + peer_notify.enter_scene_token = 1337; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::EnterScenePeerNotify, metadata, &peer_notify); + self.packets_to_send_tx.send(message).unwrap(); + } + + fn process_scene_init_finish(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::SceneInitFinishReq, rsp: &mut proto::SceneInitFinishRsp) { + // TODO! + rsp.enter_scene_token = 1337; + + let mut world_data_notify = proto::WorldDataNotify::default(); + let mut p1 = proto::PropValue::default(); + p1.r#type = 1; + p1.val = 8; + p1.value = Some(proto::prop_value::Value::Ival(8)); + let mut p2 = proto::PropValue::default(); + p2.r#type = 2; + p2.val = 0; + p2.value = Some(proto::prop_value::Value::Ival(0)); + world_data_notify.world_prop_map.insert(1, p1); // World level + world_data_notify.world_prop_map.insert(2, p2); + let message = IpcMessage::new_from_proto(conv, proto::PacketId::WorldDataNotify, metadata, &world_data_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut online_player_info = proto::OnlinePlayerInfo::default(); + online_player_info.uid = 0x1234; + online_player_info.nickname = "Fukker".to_string(); + online_player_info.player_level = 60; + online_player_info.mp_setting_type = proto::MpSettingType::MpSettingEnterAfterApply as i32; + online_player_info.cur_player_num_in_world = 1; + online_player_info.world_level = 8; + online_player_info.name_card_id = 210051; + online_player_info.signature = "Fuck you!".to_string(); + // TODO: Field 12! + + let mut world_player_notify = proto::WorldPlayerInfoNotify::default(); + world_player_notify.player_info_list = vec![online_player_info.clone()]; + world_player_notify.player_uid_list = vec![0x1234]; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::WorldPlayerInfoNotify, metadata, &world_player_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut scene_player_info_e = proto::ScenePlayerInfo::default(); + scene_player_info_e.uid = 0x1234; + scene_player_info_e.peer_id = 1; + scene_player_info_e.name = "Fukker".to_string(); + scene_player_info_e.scene_id = 3; + scene_player_info_e.online_player_info = Some(online_player_info); + let mut scene_player_info = proto::ScenePlayerInfoNotify::default(); + scene_player_info.player_info_list = vec![scene_player_info_e]; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::ScenePlayerInfoNotify, metadata, &scene_player_info); + self.packets_to_send_tx.send(message).unwrap(); + + let mut avatar_enter_info = proto::AvatarEnterSceneInfo::default(); + avatar_enter_info.avatar_guid = 0xCAFE; + avatar_enter_info.avatar_entity_id = 42; + avatar_enter_info.weapon_guid = 0xBABE; + avatar_enter_info.weapon_entity_id = 32; + let mut mp_level_info = proto::MpLevelEntityInfo::default(); + mp_level_info.entity_id = 146; + mp_level_info.authority_peer_id = 1; + let mut player_enter_info_notify = proto::PlayerEnterSceneInfoNotify::default(); + player_enter_info_notify.enter_scene_token = 1337; + player_enter_info_notify.avatar_enter_info = vec![avatar_enter_info]; + player_enter_info_notify.cur_avatar_entity_id = 42; + player_enter_info_notify.mp_level_entity_info = Some(mp_level_info); + let message = IpcMessage::new_from_proto(conv, proto::PacketId::PlayerEnterSceneInfoNotify, metadata, &player_enter_info_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut game_time_notify = proto::PlayerGameTimeNotify::default(); + game_time_notify.game_time = 5*60*60; + game_time_notify.uid = 0x1234; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::PlayerGameTimeNotify, metadata, &game_time_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut scene_time_notify = proto::SceneTimeNotify::default(); + scene_time_notify.scene_id = 3; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::SceneTimeNotify, metadata, &scene_time_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut scene_data_notify = proto::SceneDataNotify::default(); + let message = IpcMessage::new_from_proto(conv, proto::PacketId::SceneDataNotify, metadata, &scene_data_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut host_notify = proto::HostPlayerNotify::default(); + host_notify.host_uid = 0x1234; + host_notify.host_peer_id = 1; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::HostPlayerNotify, metadata, &host_notify); + self.packets_to_send_tx.send(message).unwrap(); + + let mut scene_avatar_info = proto::SceneAvatarInfo::default(); + scene_avatar_info.uid = 0x1234; + scene_avatar_info.avatar_id = 10000007; + scene_avatar_info.guid = 0xCAFE; + scene_avatar_info.peer_id = 1; + scene_avatar_info.skill_depot_id = 704; + scene_avatar_info.born_time = 1609004613; + let mut scene_entity_info = proto::SceneEntityInfo::default(); + scene_entity_info.entity_type = proto::ProtEntityType::ProtEntityAvatar as i32; + scene_entity_info.entity_id = 42; + scene_entity_info.life_state = 1; + scene_entity_info.entity = Some(proto::scene_entity_info::Entity::Avatar(scene_avatar_info)); + let mut scene_team_avatar = proto::SceneTeamAvatar::default(); + scene_team_avatar.player_uid = 0x1234; + scene_team_avatar.avatar_guid = 0xCAFE; + scene_team_avatar.scene_id = 3; + scene_team_avatar.entity_id = 42; + scene_team_avatar.weapon_guid = 0xBABE; + scene_team_avatar.weapon_entity_id = 32; + scene_team_avatar.is_player_cur_avatar = true; + scene_team_avatar.scene_entity_info = Some(scene_entity_info); + let mut scene_team_update = proto::SceneTeamUpdateNotify::default(); + scene_team_update.scene_team_avatar_list = vec![scene_team_avatar]; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::SceneTeamUpdateNotify, metadata, &scene_team_update); + self.packets_to_send_tx.send(message).unwrap(); + } + + fn process_enter_done(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::EnterSceneDoneReq, rsp: &mut proto::EnterSceneDoneRsp) { + rsp.enter_scene_token = req.enter_scene_token; + + let mut appear_notify = proto::SceneEntityAppearNotify::default(); + //appear_notify.entity_list = ; // TODO: first char should appear! + appear_notify.appear_type = proto::VisionType::VisionBorn as i32; + let message = IpcMessage::new_from_proto(conv, proto::PacketId::SceneEntityAppearNotify, metadata, &appear_notify); + self.packets_to_send_tx.send(message).unwrap(); + } + + fn process_post_enter_scene(&self, conv: u32, metadata: &proto::PacketHead, req: &proto::PostEnterSceneReq, rsp: &mut proto::PostEnterSceneRsp) { + rsp.enter_scene_token = 1337; + } +} diff --git a/src/server/ipc_message.rs b/src/server/ipc_message.rs index 69a8058..c3d9c44 100644 --- a/src/server/ipc_message.rs +++ b/src/server/ipc_message.rs @@ -1 +1,27 @@ -pub struct IpcMessage(pub u32, pub u16, pub Vec, pub Vec); +use crate::proto; + +use prost; +use prost::Message; + +pub struct IpcMessage(pub u32, pub proto::PacketId, pub Vec, pub Vec); + +impl IpcMessage { + pub fn new_from_proto(conv: u32, packet_id: proto::PacketId, metadata: &proto::PacketHead, data: &M) -> IpcMessage { + println!("Replying with {:?}", packet_id); + + let mut buf: Vec = vec!(); + + data.encode(&mut buf).unwrap(); + + let mut metabuf: Vec = vec!(); + + metadata.encode(&mut metabuf).unwrap(); + + return IpcMessage( + conv, + packet_id, + metabuf, + buf + ); + } +} diff --git a/src/server/mod.rs b/src/server/mod.rs index a49c922..86f8335 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,9 +1,13 @@ mod network_server; mod game_server; +mod game_world; +mod auth_manager; mod client_connection; mod ipc_message; pub use self::network_server::NetworkServer; pub use self::game_server::GameServer; +pub use self::game_world::GameWorld; +pub use self::auth_manager::AuthManager; pub use self::client_connection::ClientConnection; pub use self::ipc_message::IpcMessage; diff --git a/src/server/network_server.rs b/src/server/network_server.rs index f282365..93810f2 100644 --- a/src/server/network_server.rs +++ b/src/server/network_server.rs @@ -7,12 +7,21 @@ use std::thread; use std::sync::mpsc; use std::sync::{Arc, RwLock, Mutex}; +use num_derive::FromPrimitive; +use num_traits::FromPrimitive; +use num_derive::ToPrimitive; +use num_traits::ToPrimitive; + use crate::utils::HandshakePacket; use crate::utils::DataPacket; use crate::server::ClientConnection; +use crate::server::GameServer; use crate::server::IpcMessage; +use crate::proto; use crate::proto::PacketHead; +use crate::proto::GetPlayerTokenRsp; +use crate::proto::get_player_token_rsp; use prost::Message; @@ -74,19 +83,29 @@ impl NetworkServer { loop { let IpcMessage(conv, packet_id, metadata, data) = packets_to_send_rx.recv().unwrap(); - let data = DataPacket::new(packet_id, metadata, data); + let data_packet = DataPacket::new(packet_id.clone() as u16, metadata, data.clone()); match clients.lock().unwrap().get_mut(&conv) { Some(client) => { - client.send_udp_packet(&data.to_bytes()); + let bytes = data_packet.to_bytes(); + client.send_udp_packet(&bytes); - // TODO: here, if encryption key was changed, do so + if packet_id == proto::PacketId::GetPlayerTokenRsp { + // TODO: a bit hacky! + let token_rsp = GetPlayerTokenRsp::decode(&mut Cursor::new(data)).unwrap(); + client.update_key(token_rsp.secret_key_seed); + } }, None => panic!("Unknown client conv: {}", conv), }; } }); + let game_thread = thread::spawn(move || { + let mut gs = GameServer::new(packets_to_process_rx, packets_to_send_tx); + gs.run(); + }); + let mut buffer = [0u8; 65536]; loop { @@ -126,7 +145,7 @@ impl NetworkServer { } }, Err(e) => { - print!("Error constructing handshake: {:#?}", e); + //print!("Error constructing handshake: {:#?}", e); let conv = kcp::get_conv(packet_bytes); let packets = match self.clients.lock().unwrap().get_mut(&conv) { @@ -156,13 +175,21 @@ impl NetworkServer { Err(e) => panic!("Malformed packet header: {:#?}!", e), }; - print!("Got packet with header: {:#?} and ID {}\n", head, data.packet_id); + let packet_id: proto::PacketId = match FromPrimitive::from_u16(data.packet_id) { + Some(packet_id) => packet_id, + None => { + println!("Skipping unknown packet ID {}", data.packet_id); + return; + } + }; + + println!("Got packet {:?}", packet_id); let sender = match &self.packets_to_process_tx { Some(sender) => sender, None => panic!("Processing queue wasn't set up!"), }; - sender.send( IpcMessage(conv, data.packet_id, data.metadata, data.data) ).unwrap(); + sender.send( IpcMessage(conv, packet_id, data.metadata, data.data) ).unwrap(); } }