diff --git a/RustySamovar/Cargo.toml b/RustySamovar/Cargo.toml index b362c60..a80b94e 100644 --- a/RustySamovar/Cargo.toml +++ b/RustySamovar/Cargo.toml @@ -17,6 +17,8 @@ packet-processor-macro = { path = "../packet-processor-macro" } packet-processor = { path = "../packet-processor" } rs-ipc = { path = "../rs-ipc" } excel-hash-wrapper-macro = { path = "../excel-hash-wrapper-macro" } +rs-nodeconf = { path = "../rs-nodeconf" } +rs-utils = { path = "../rs-utils" } prost = "0.8" bytes = "1.1.0" diff --git a/RustySamovar/src/dbmanager/database_manager.rs b/RustySamovar/src/dbmanager/database_manager.rs index 411274f..8ef8028 100644 --- a/RustySamovar/src/dbmanager/database_manager.rs +++ b/RustySamovar/src/dbmanager/database_manager.rs @@ -12,7 +12,6 @@ use crate::collection; use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult, Database}; use sea_orm::entity::prelude::*; use crate::JsonManager; -use crate::server::AuthManager; use crate::utils::IdManager; pub use super::player_info::Model as PlayerInfo; diff --git a/RustySamovar/src/entitymanager/entity_manager.rs b/RustySamovar/src/entitymanager/entity_manager.rs index 470876d..be07098 100644 --- a/RustySamovar/src/entitymanager/entity_manager.rs +++ b/RustySamovar/src/entitymanager/entity_manager.rs @@ -15,10 +15,11 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::utils::{IdManager, TimeManager}; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; use crate::luamanager::Vector; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; use super::entities::Entity; #[derive(Debug)] diff --git a/RustySamovar/src/jsonmanager/shop_goods.rs b/RustySamovar/src/jsonmanager/shop_goods.rs index fc89bcc..7e5e06c 100644 --- a/RustySamovar/src/jsonmanager/shop_goods.rs +++ b/RustySamovar/src/jsonmanager/shop_goods.rs @@ -2,7 +2,7 @@ use chrono::NaiveDateTime; use serde::{Serialize, Deserialize}; -use crate::utils::TimeManager; +use rs_utils::TimeManager; #[derive(Deserialize, Clone)] #[serde(rename_all="PascalCase")] diff --git a/RustySamovar/src/main.rs b/RustySamovar/src/main.rs index c0f3c80..4fdb408 100644 --- a/RustySamovar/src/main.rs +++ b/RustySamovar/src/main.rs @@ -7,7 +7,7 @@ extern crate num_derive; use std::thread; -mod node; +use rs_nodeconf::NodeConfig; mod server; mod utils; @@ -18,12 +18,12 @@ mod entitymanager; mod subsystems; -use server::NetworkServer; use dbmanager::DatabaseManager; use jsonmanager::JsonManager; use luamanager::LuaManager; use subsystems::EntitySubsystem; use entitymanager::EntityManager; +use crate::server::GameServer; fn main() { //pretty_env_logger::init(); @@ -35,6 +35,8 @@ fn main() { .with_test_writer() .init(); - let mut ns = NetworkServer::new("0.0.0.0", 4242).unwrap(); - ns.run().expect("Failed to serve!"); + let nc = NodeConfig::new(); + let mut gs = GameServer::new(&nc); + + gs.run(); } diff --git a/RustySamovar/src/node/config.rs b/RustySamovar/src/node/config.rs deleted file mode 100644 index dd889fa..0000000 --- a/RustySamovar/src/node/config.rs +++ /dev/null @@ -1,35 +0,0 @@ -use rs_ipc::{PubSocket, PullSocket, PushSocket, Result, SubSocket}; - -pub struct NodeConfig { - pub in_queue_addr: String, - pub in_queue_port: u16, - pub out_queue_addr: String, - pub out_queue_port: u16, -} - -impl NodeConfig { - pub fn new() -> Self { - NodeConfig { - in_queue_addr: "127.0.0.1".to_string(), - in_queue_port: 9012, - out_queue_addr: "127.0.0.1".to_string(), - out_queue_port: 9014, - } - } - - pub fn bind_in_queue(&self) -> Result { - PubSocket::bind_tcp(&self.in_queue_addr, self.in_queue_port) - } - - pub fn bind_out_queue(&self) -> Result { - PullSocket::bind_tcp(&self.out_queue_addr, self.out_queue_port) - } - - pub fn connect_in_queue(&self) -> Result { - SubSocket::connect_tcp(&self.in_queue_addr, self.in_queue_port) - } - - pub fn connect_out_queue(&self) -> Result { - PushSocket::connect_tcp(&self.out_queue_addr, self.out_queue_port) - } -} \ No newline at end of file diff --git a/RustySamovar/src/node/mod.rs b/RustySamovar/src/node/mod.rs deleted file mode 100644 index 6368087..0000000 --- a/RustySamovar/src/node/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod config; - -pub use config::NodeConfig; \ No newline at end of file diff --git a/RustySamovar/src/server/auth_manager.rs b/RustySamovar/src/server/auth_manager.rs deleted file mode 100644 index 0fcb951..0000000 --- a/RustySamovar/src/server/auth_manager.rs +++ /dev/null @@ -1,137 +0,0 @@ -use openssl::hash::MessageDigest; -use openssl::pkey::PKey; -use openssl::rsa::Padding; -use openssl::sign::Signer; -use std::sync::mpsc; -use std::collections::HashMap; -use std::convert::TryInto; - -use prost::Message; - -use rs_ipc::{IpcMessage, PushSocket}; - -use packet_processor_macro::*; -#[macro_use] -use packet_processor::*; -use crate::node::NodeConfig; - -#[packet_processor(GetPlayerTokenReq)] -pub struct AuthManager { - conv_to_user: HashMap, - user_to_conv: HashMap, - //packets_to_send_tx: mpsc::Sender, - packets_to_send_tx: PushSocket, -} - -impl AuthManager { - pub const SPOOFED_PLAYER_UID: u32 = 1337; - - pub fn new(node_config: &NodeConfig) -> AuthManager { - let mut am = AuthManager { - conv_to_user: HashMap::new(), - user_to_conv: HashMap::new(), - packet_callbacks: HashMap::new(), - packets_to_send_tx: node_config.connect_out_queue().unwrap(), - }; - - am.register(); - - return am; - } - - pub fn process_get_player_token(&mut self, conv: u32, metadata: &proto::PacketHead, req: &proto::GetPlayerTokenReq, rsp: &mut proto::GetPlayerTokenRsp) { - let seed: u64 = 0xBABECAFEF00D; // TODO: use real value! - let client_hardcoded_seed: u64 = 0x12345678; - let uid = self.get_uid_by_account_id(req.account_uid.parse().unwrap()); - - rsp.account_type = req.account_type; - rsp.account_uid = req.account_uid.clone(); - rsp.token = req.account_token.clone(); - rsp.secret_key_seed = seed; // TODO: temporary workaround! - rsp.uid = uid; - - if req.key_id > 0 { // TODO: detect client version properly! - // Versions 2.7.5x+ use different algorithm for key initialization - - // TODO: as of now (2022-05-16) this algorithm here is more of a PoC, because we can't really sign the data - // or decrypt the client seed we're getting from the client. - // - // Connecting to our server still requires patching the client to disable signature verification and hardcoding - // some known client seed value. This will allow the patched client to connect to official servers (beware of - // the ban for modding the client!) - // - // An alternative approach to hardcoding the client seed would be to employ RCE in WindSeedClientNotify to extract - // the seed from the client itself. That still would require patching the client though (to allow invalid signatures), - // so it's of a very little difference to us. - // - // Another alternative is to replace keys inside global-metadata.dat file, but that requires writing an encryption - // tool. While still possible, it's tiresome, and won't allow patched client to connect to official server without - // switching back and forth between two versions of global-metadata.dat file. - - let key_id = req.key_id as u8; - - let rsa_key_collection = mhycrypt::load_rsa_keys("RSAConfig", "keys"); - let keys = match rsa_key_collection.get(&key_id) { - Some(keys) => keys, - None => panic!("Unknown key ID {}!", key_id), - }; - - // Decrypt received client seed - - let client_seed_encrypted = base64::decode(&req.client_rand_key).unwrap(); - - let mut dec_buf: Vec = vec![0; 256]; - - let client_seed = match keys.signing_key.private_decrypt(&client_seed_encrypted, &mut dec_buf, Padding::PKCS1) { - Ok(seed_size) => { - // Note: from_be_bytes here, because client seems to swap order of bytes for the seed - u64::from_be_bytes(dec_buf[0..seed_size].try_into().unwrap()) - }, - Err(e) => { // TODO: must panic here! - println!("Error decrypting client seed: {}", e); - client_hardcoded_seed // TODO: temporary workaround! - }, - }; - - // Encrypt server seed which we'll use in negotiating with the client - - let mut enc_buf: Vec = vec![0; 256]; - - // Note: to_be_bytes here, because client seems to swap order of bytes for the seed - let seed_bytes = (seed ^ client_seed).to_be_bytes(); - - let len = keys.encrypt_key.public_encrypt(&seed_bytes, &mut enc_buf, Padding::PKCS1).unwrap(); - - // Sign it - let keypair = PKey::from_rsa(keys.signing_key.clone()).unwrap(); - let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap(); - let signature = signer.sign_oneshot_to_vec(&seed_bytes).unwrap(); - - rsp.key_id = key_id as u32; - rsp.server_rand_key = base64::encode(&enc_buf); - rsp.sign = base64::encode(&signature); - } - - self.conv_to_user.insert(conv, uid); - self.user_to_conv.insert(uid, conv); - } - - fn get_uid_by_account_id(&self, account_uid: u32) -> u32 { - // TODO! - return AuthManager::SPOOFED_PLAYER_UID; - } - - pub fn resolve_conv(&self, conv: u32) -> Option { - match self.conv_to_user.get(&conv) { - Some(uid) => return Some(*uid), - None => return None, - }; - } - - pub fn resolve_uid(&self, uid: u32) -> Option { - match self.user_to_conv.get(&uid) { - Some(conv) => return Some(*conv), - None => return None, - }; - } -} diff --git a/RustySamovar/src/server/client_connection.rs b/RustySamovar/src/server/client_connection.rs deleted file mode 100644 index 4c45830..0000000 --- a/RustySamovar/src/server/client_connection.rs +++ /dev/null @@ -1,121 +0,0 @@ -use std::io; -use std::io::Read; -use std::fs; -use std::net::SocketAddr; -use std::net::UdpSocket; -use std::io::Write; -use std::time::SystemTime; -use std::convert::TryInto; - -use crate::utils::TimeManager; - -extern crate kcp; -extern crate mhycrypt; - -use kcp::Kcp; - -pub struct ClientConnection { - conv: u32, - token: u32, - ikcp: Kcp, - established_time: SystemTime, - key: [u8; 0x1000], - pending_seed: Option, -} - -pub struct Source -{ - address: Option, - socket: UdpSocket, -} - -impl Write for Source { - fn write(&mut self, data: &[u8]) -> io::Result { - return self.socket.send_to(data, self.address.expect("Unknown destination address!")); - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl ClientConnection { - pub fn new(socket: UdpSocket, conv: u32, token: u32) -> ClientConnection { - let s = Source { - address: None, - socket: socket, - }; - - return ClientConnection { - conv: conv, - token: token, - ikcp: Kcp::new(conv, token, s), - established_time: SystemTime::now(), - key: ClientConnection::read_key("master").try_into().expect("Incorrect master key"), - pending_seed: None, - }; - } - - pub fn update_source(&mut self, new_source: SocketAddr) { - self.ikcp.output.0.address = Some(new_source); - } - - 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(); - self.ikcp.flush().unwrap(); - loop { - let mut buf = [0u8; 0x20000]; - match self.ikcp.recv(&mut buf) { - Err(_) => break, - Ok(size) => { - #[cfg(feature = "raw_packet_dump")] - { - use pretty_hex::*; - let cfg = HexConfig {title: true, width: 16, group: 0, ascii: true, ..HexConfig::default() }; - println!("{:?}", buf[..size].to_vec().hex_conf(cfg)); - } - mhycrypt::mhy_xor(&mut buf[..size], &self.key); - let data = buf[..size].to_owned(); - packets.push(data); - }, - } - } - self.ikcp.update(self.elapsed_time_millis()).unwrap(); - return packets; - } - - pub fn update_key(&mut self, seed: u64) { - 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(&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"); - return buffer; - } - - fn elapsed_time_millis(&self) -> u32 { - return TimeManager::duration_since(self.established_time).try_into().unwrap(); - } - - pub fn send_udp_packet(&mut self, data: &[u8]) { - 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/RustySamovar/src/server/game_server.rs b/RustySamovar/src/server/game_server.rs index 61b42b9..3d1460f 100644 --- a/RustySamovar/src/server/game_server.rs +++ b/RustySamovar/src/server/game_server.rs @@ -14,7 +14,7 @@ use crate::LuaManager; use crate::server::LoginManager; use std::sync::Arc; use crate::entitymanager::EntityManager; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; use crate::subsystems::{InventorySubsystem, NpcSubsystem, ShopSubsystem}; use crate::subsystems::misc::{PauseSubsystem, SceneSubsystem, SocialSubsystem, TeleportSubsystem}; diff --git a/RustySamovar/src/server/login_manager.rs b/RustySamovar/src/server/login_manager.rs index ec142ea..4b83b62 100644 --- a/RustySamovar/src/server/login_manager.rs +++ b/RustySamovar/src/server/login_manager.rs @@ -13,11 +13,11 @@ use crate::{DatabaseManager, luamanager}; use crate::JsonManager; use crate::utils::{AvatarBuilder, IdManager, Remapper}; -use crate::utils::TimeManager; +use rs_utils::TimeManager; use crate::dbmanager::database_manager::AvatarInfo as DbAvatarInfo; use crate::entitymanager::EntityManager; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; #[packet_processor(PlayerLoginReq)] pub struct LoginManager { diff --git a/RustySamovar/src/server/mod.rs b/RustySamovar/src/server/mod.rs index df302c5..e0e1dc7 100644 --- a/RustySamovar/src/server/mod.rs +++ b/RustySamovar/src/server/mod.rs @@ -1,13 +1,7 @@ -mod network_server; mod game_server; mod game_world; -mod auth_manager; mod login_manager; -mod client_connection; -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::login_manager::LoginManager; -pub use self::client_connection::ClientConnection; diff --git a/RustySamovar/src/server/network_server.rs b/RustySamovar/src/server/network_server.rs deleted file mode 100644 index 49ecf99..0000000 --- a/RustySamovar/src/server/network_server.rs +++ /dev/null @@ -1,259 +0,0 @@ -use std::fmt; -use std::net::UdpSocket; -use std::net::SocketAddr; -use std::collections::HashMap; -use std::io::Cursor; -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::AuthManager; - -use rs_ipc::{IpcMessage, PullSocket, PushSocket}; - -use proto::PacketHead; -use proto::GetPlayerTokenRsp; -//use proto::get_player_token_rsp; - -use prost::Message; - -use rs_ipc::{SubSocket, PubSocket}; - -use packet_processor::{PacketProcessor, EasilyUnpackable}; -use crate::node::NodeConfig; - -extern crate kcp; - -/* - This is used to convert async operations into sync ones - */ -trait Block { - fn wait(self) -> ::Output - where Self: Sized, Self: futures::Future - { - futures::executor::block_on(self) - } -} - -impl Block for F - where F: futures::Future -{} - -// ------------- - -pub struct NetworkServer { - socket: UdpSocket, - clients: Arc>>, - node_config: NodeConfig, - packets_to_process_tx: PubSocket, -} - -#[derive(Debug, Clone)] -pub struct NetworkServerError { - reason: String, -} - -impl NetworkServerError { - pub fn new(reason: &str) -> NetworkServerError { - return NetworkServerError {reason: reason.to_string()}; - } -} - -impl fmt::Display for NetworkServerError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "NetworkServerError: {}", self.reason) - } -} - -impl NetworkServer { - pub fn new(host: &str, port: i16) -> Result { - let node_config = NodeConfig::new(); - - let mut packets_to_process_tx = node_config.bind_in_queue().unwrap(); - - let gs = NetworkServer { - socket: match UdpSocket::bind(format!("{}:{}", host, port).to_string()) { - Ok(socket) => socket, - Err(e) => return Err(NetworkServerError::new(format!("Failed to bind socket: {}", e).as_str())), - }, - clients: Arc::new(Mutex::new(HashMap::new())), - node_config: node_config, - packets_to_process_tx: packets_to_process_tx, - }; - - print!("Connection established\n"); - - return Ok(gs); - } - - pub fn run(&mut self) -> Result { - print!("Starting server\n"); - - let mut packets_to_send_rx = self.node_config.bind_out_queue().unwrap(); - - let clients = self.clients.clone(); - let mut auth_manager = Arc::new(Mutex::new(AuthManager::new(&self.node_config))); - let am = auth_manager.clone(); - - let packet_relaying_thread = thread::spawn(move || { - loop { - let IpcMessage(packet_id, user_id, metadata, data) = packets_to_send_rx.recv().unwrap(); - - let conv = match packet_id { - proto::PacketId::GetPlayerTokenRsp => user_id, // Mapping is not performed on those - _ => am.lock().unwrap().resolve_uid(user_id).unwrap_or_else(|| panic!("Unknown user ID {}!", user_id)), - }; - - let data_packet = DataPacket::new(packet_id.clone() as u16, metadata, data.clone()); - - match clients.lock().unwrap().get_mut(&conv) { - Some(client) => { - let bytes = data_packet.to_bytes(); - client.send_udp_packet(&bytes); - - if packet_id == proto::PacketId::GetPlayerTokenRsp { - // TODO: a bit hacky! - let token_rsp: GetPlayerTokenRsp = EasilyUnpackable::from(&data); - client.update_key(token_rsp.secret_key_seed); - } - }, - None => panic!("Unknown client conv: {}", conv), - }; - } - }); - - let game_thread = thread::spawn(move || { - let node_config = NodeConfig::new(); - let mut gs = GameServer::new(&node_config); - gs.run(); - }); - - let mut buffer = [0u8; 65536]; - - loop { - match self.socket.recv_from(&mut buffer) { - Ok( (bytes_number, source_address) ) => self.process_udp_packet(source_address, &buffer[..bytes_number], &mut auth_manager), - Err(e) => panic!("Failed to receive data: {}", e), - } - } - - //packet_relaying_thread.join().unwrap(); - - return Ok(0); - } - - fn process_udp_packet(&mut self, source_address: SocketAddr, packet_bytes: &[u8], auth_manager: &mut Arc>) { - //print!("Received packet! Len = {}\n", packet_bytes.len()); - - let hs_packet = HandshakePacket::new(packet_bytes); - - match hs_packet { - Ok(hs_packet) => { - //print!("Received handshake packet: {:#?}\n", hs_packet); - if hs_packet.is_connect() { - //print!("Sending reply to CONNECT\n"); - // TODO: assign conv and token! - let conv = 0x96969696u32; - let token = 0x42424242u32; - - let reply = HandshakePacket::new_conv(conv, token); - - let mut client = ClientConnection::new(self.socket.try_clone().unwrap(), conv, token); - client.update_source(source_address); - - self.clients.lock().unwrap().insert(conv, client); - - self.socket.send_to(&reply.to_bytes(), source_address).expect("Failed to send data!"); - } - }, - Err(e) => { - //print!("Error constructing handshake: {:#?}", e); - let conv = kcp::get_conv(packet_bytes); - - let packets = match self.clients.lock().unwrap().get_mut(&conv) { - Some(client) => { - client.update_source(source_address); - - client.process_udp_packet(packet_bytes) - } - None => panic!("Unknown client conv: {}", conv), - }; - - for packet in packets.iter() { - self.process_game_packet(conv, packet, auth_manager); - } - }, - }; - } - - fn process_game_packet(&mut self, conv: u32, packet: &[u8], auth_manager: &mut Arc>) { - let data = match DataPacket::new_from_bytes(packet) { - Ok(data) => data, - Err(e) => panic!("Malformed data packet: {:#?}!", e), - }; - - let head = match PacketHead::decode(&mut Cursor::new(&data.metadata)) { - Ok(head) => head, - Err(e) => panic!("Malformed packet header: {:#?}!", e), - }; - - 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; - } - }; - - let user_id = match packet_id { - proto::PacketId::GetPlayerTokenReq => { - auth_manager.lock().unwrap().process(conv, packet_id, data.metadata, data.data); - return; - }, - _ => match auth_manager.lock().unwrap().resolve_conv(conv) { - None => { - println!("Unknown user with conv {}! Skipping", conv); - return; - }, - Some(user_id) => user_id, - }, - }; - - if packet_id == proto::PacketId::UnionCmdNotify { - let union: proto::UnionCmdNotify = EasilyUnpackable::from(&data.data); - for u_cmd in union.cmd_list.into_iter() { - self.send_packet_to_process(user_id, u_cmd.message_id as u16, &data.metadata, &u_cmd.body); - } - } else { - self.send_packet_to_process(user_id, data.packet_id, &data.metadata, &data.data); - } - } - - fn send_packet_to_process(&mut self, user_id: u32, packet_id: u16, metadata: &[u8], data: &[u8]) - { - /*let sender: &mut PubSocket = match &self.packets_to_process_tx { - Some(mut sender) => &mut sender, - None => panic!("Processing queue wasn't set up!"), - };*/ - - let packet_id: proto::PacketId = match FromPrimitive::from_u16(packet_id) { - Some(packet_id) => packet_id, - None => { - println!("Skipping unknown packet ID {}", packet_id); - return; - }, - }; - - println!("Got packet {:?}", packet_id); - self.packets_to_process_tx.send( IpcMessage(packet_id, user_id, metadata.to_vec(), data.to_vec()) ); - } -} diff --git a/RustySamovar/src/subsystems/entity_subsystem/entity_subsystem.rs b/RustySamovar/src/subsystems/entity_subsystem/entity_subsystem.rs index 8b8fc0b..b0f439f 100644 --- a/RustySamovar/src/subsystems/entity_subsystem/entity_subsystem.rs +++ b/RustySamovar/src/subsystems/entity_subsystem/entity_subsystem.rs @@ -16,10 +16,11 @@ use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; use crate::entitymanager::EntityManager; -use crate::utils::{IdManager, TimeManager}; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; use crate::luamanager::Vector; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; #[packet_processor( CombatInvocationsNotify, diff --git a/RustySamovar/src/subsystems/inventory_subsystem/inventory_subsystem.rs b/RustySamovar/src/subsystems/inventory_subsystem/inventory_subsystem.rs index df177fe..57c744d 100644 --- a/RustySamovar/src/subsystems/inventory_subsystem/inventory_subsystem.rs +++ b/RustySamovar/src/subsystems/inventory_subsystem/inventory_subsystem.rs @@ -5,7 +5,7 @@ use crate::{DatabaseManager, JsonManager}; #[macro_use] use packet_processor::*; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; pub struct InventorySubsystem { packets_to_send_tx: PushSocket, diff --git a/RustySamovar/src/subsystems/misc/npc.rs b/RustySamovar/src/subsystems/misc/npc.rs index e0f273a..72283a9 100644 --- a/RustySamovar/src/subsystems/misc/npc.rs +++ b/RustySamovar/src/subsystems/misc/npc.rs @@ -15,8 +15,9 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::node::NodeConfig; -use crate::utils::{IdManager, TimeManager}; +use rs_nodeconf::NodeConfig; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( NpcTalkReq, diff --git a/RustySamovar/src/subsystems/misc/pause.rs b/RustySamovar/src/subsystems/misc/pause.rs index 03a9b03..629e425 100644 --- a/RustySamovar/src/subsystems/misc/pause.rs +++ b/RustySamovar/src/subsystems/misc/pause.rs @@ -15,8 +15,9 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::node::NodeConfig; -use crate::utils::{IdManager, TimeManager}; +use rs_nodeconf::NodeConfig; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( PlayerSetPauseReq, diff --git a/RustySamovar/src/subsystems/misc/scene.rs b/RustySamovar/src/subsystems/misc/scene.rs index 65f84b2..404b9e0 100644 --- a/RustySamovar/src/subsystems/misc/scene.rs +++ b/RustySamovar/src/subsystems/misc/scene.rs @@ -15,8 +15,9 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::node::NodeConfig; -use crate::utils::{IdManager, TimeManager}; +use rs_nodeconf::NodeConfig; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( GetSceneAreaReq, diff --git a/RustySamovar/src/subsystems/misc/shop.rs b/RustySamovar/src/subsystems/misc/shop.rs index 8349f81..d548cf2 100644 --- a/RustySamovar/src/subsystems/misc/shop.rs +++ b/RustySamovar/src/subsystems/misc/shop.rs @@ -15,9 +15,10 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::node::NodeConfig; +use rs_nodeconf::NodeConfig; use crate::subsystems::InventorySubsystem; -use crate::utils::{IdManager, TimeManager}; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( GetShopReq, diff --git a/RustySamovar/src/subsystems/misc/social.rs b/RustySamovar/src/subsystems/misc/social.rs index dce135e..ebc94fb 100644 --- a/RustySamovar/src/subsystems/misc/social.rs +++ b/RustySamovar/src/subsystems/misc/social.rs @@ -17,8 +17,9 @@ use packet_processor_macro::*; use packet_processor::*; use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; -use crate::node::NodeConfig; -use crate::utils::{IdManager, TimeManager}; +use rs_nodeconf::NodeConfig; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( GetPlayerBlacklistReq, diff --git a/RustySamovar/src/subsystems/misc/teleport.rs b/RustySamovar/src/subsystems/misc/teleport.rs index 2338a6b..c4a41e4 100644 --- a/RustySamovar/src/subsystems/misc/teleport.rs +++ b/RustySamovar/src/subsystems/misc/teleport.rs @@ -17,8 +17,9 @@ use serde_json::de::Read; use crate::{DatabaseManager, JsonManager, LuaManager}; use crate::entitymanager::EntityManager; use crate::luamanager::Vector; -use crate::node::NodeConfig; -use crate::utils::{IdManager, TimeManager}; +use rs_nodeconf::NodeConfig; +use crate::utils::{IdManager}; +use rs_utils::TimeManager; #[packet_processor( SceneTransToPointReq, diff --git a/RustySamovar/src/utils/data_packet.rs b/RustySamovar/src/utils/data_packet.rs deleted file mode 100644 index e798fef..0000000 --- a/RustySamovar/src/utils/data_packet.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::fmt; -use std::convert::TryInto; - -#[derive(Debug)] -pub struct DataDecError { - reason: String, -} - -#[repr(packed)] -pub struct DataPacketSmallest // Not actually used, just represents the general structure -{ - start_magic: u16, - packet_id: u16, - metadata_size: u16, - data_size: u32, - //metadata: [0u8; metadata_size], - //data: [0u8; data_size], - end_magic: u16, -} - -#[derive(Debug)] -pub struct DataPacket -{ - pub packet_id: u16, - pub metadata: Vec, - pub data: Vec, -} - -impl DataPacket { - const DATA_MAGIC_START: u16 = 0x4567; - const DATA_MAGIC_END: u16 = 0x89AB; - - pub fn new(packet_id: u16, metadata: Vec, data: Vec) -> DataPacket { - return DataPacket { - packet_id: packet_id, - data: data, - metadata: metadata, - }; - } - - pub fn new_from_bytes(raw_data: &[u8]) -> Result { - if raw_data.len() < std::mem::size_of::() { - return Err(DataDecError {reason: "Size is too small!".to_string()}); - } - - // unwrap() here are valid as we're cutting exactly 4 bytes of data - let start_magic = u16::from_be_bytes(raw_data[0..2].try_into().unwrap()); - let end_magic = u16::from_be_bytes(raw_data[raw_data.len()-2..].try_into().unwrap()); - - if (start_magic == DataPacket::DATA_MAGIC_START) && (end_magic == DataPacket::DATA_MAGIC_END) { - let packet_id = u16::from_be_bytes(raw_data[2..4].try_into().unwrap()); - let metadata_size = u16::from_be_bytes(raw_data[4..6].try_into().unwrap()) as usize; - let data_size = u32::from_be_bytes(raw_data[6..10].try_into().unwrap()) as usize; - - let expected_size = std::mem::size_of::() + metadata_size + data_size; - - if raw_data.len() != expected_size { - return Err(DataDecError {reason: format!("Wrong packet size: expected {}, got {} (header {}, payload {})!", expected_size, raw_data.len(), std::mem::size_of::(), metadata_size + data_size)}); - } - - return Ok(DataPacket { - packet_id: packet_id, - metadata: raw_data[10..metadata_size+10].to_owned(), - data: raw_data[metadata_size+10..metadata_size+data_size+10].to_owned(), - }); - } else { - return Err(DataDecError {reason: format!("Unknown magic: 0x{:x} 0x{:x}", start_magic, end_magic),}); - } - } - - pub fn to_bytes(&self) -> Vec { - let mut ret = Vec::with_capacity(std::mem::size_of::() + self.data.len() + self.metadata.len()); - - ret.extend_from_slice(&DataPacket::DATA_MAGIC_START.to_be_bytes()); - ret.extend_from_slice(&self.packet_id.to_be_bytes()); - ret.extend_from_slice(&(self.metadata.len() as u16).to_be_bytes()); - ret.extend_from_slice(&(self.data.len() as u32).to_be_bytes()); - ret.extend_from_slice(&self.metadata); - ret.extend_from_slice(&self.data); - ret.extend_from_slice(&DataPacket::DATA_MAGIC_END.to_be_bytes()); - - return ret; - } -} - -impl fmt::Display for DataPacket { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "packet") - } -} diff --git a/RustySamovar/src/utils/handshake_packet.rs b/RustySamovar/src/utils/handshake_packet.rs deleted file mode 100644 index d82c88b..0000000 --- a/RustySamovar/src/utils/handshake_packet.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::fmt; -use std::convert::TryInto; - -#[derive(Debug)] -pub struct HandshakeDecError { - reason: String, -} - -#[derive(Debug)] -#[repr(C)] -pub struct HandshakePacket -{ - start_magic: u32, - param1: u32, - param2: u32, - data: u32, - end_magic: u32, -} - -impl HandshakePacket { - const HS_MAGIC_CONNECT_START: u32 = 0x000000FF; - const HS_MAGIC_CONNECT_END: u32 = 0xFFFFFFFF; - const HS_MAGIC_SEND_CONV_START: u32 = 0x00000145; - const HS_MAGIC_SEND_CONV_END: u32 = 0x14514545; - const HS_MAGIC_DISCONNECT_START: u32 = 0x00000194; - const HS_MAGIC_DISCONNECT_END: u32 = 0x19419494; - - const HS_CONNECTION_DATA: u32 = 1234567890; - - pub fn new(raw_data: &[u8]) -> Result { - if raw_data.len() != std::mem::size_of::() { - return Err(HandshakeDecError {reason: "Size mismatch!".to_string()}); - } - - // unwrap() here are valid as we're cutting exactly 4 bytes of data - let start_magic = u32::from_be_bytes(raw_data[0..4].try_into().unwrap()); - let param1 = u32::from_be_bytes(raw_data[4..8].try_into().unwrap()); - let param2 = u32::from_be_bytes(raw_data[8..12].try_into().unwrap()); - let data = u32::from_be_bytes(raw_data[12..16].try_into().unwrap()); - let end_magic = u32::from_be_bytes(raw_data[16..20].try_into().unwrap()); - - if (start_magic == HandshakePacket::HS_MAGIC_CONNECT_START) && (end_magic == HandshakePacket::HS_MAGIC_CONNECT_END) || - (start_magic == HandshakePacket::HS_MAGIC_SEND_CONV_START) && (end_magic == HandshakePacket::HS_MAGIC_SEND_CONV_END) || - (start_magic == HandshakePacket::HS_MAGIC_DISCONNECT_START) && (end_magic == HandshakePacket::HS_MAGIC_DISCONNECT_END) { - - return Ok(HandshakePacket { - start_magic: start_magic, - param1: param1, - param2: param2, - data: data, - end_magic: end_magic, - }); - } else { - return Err(HandshakeDecError {reason: format!("Unknown magic: 0x{:x} 0x{:x}", start_magic, end_magic),}); - } - } - - pub fn is_connect(&self) -> bool { - return (self.start_magic == HandshakePacket::HS_MAGIC_CONNECT_START) && - (self.end_magic == HandshakePacket::HS_MAGIC_CONNECT_END) && - (self.data == HandshakePacket::HS_CONNECTION_DATA); - } - - pub fn new_conv(conv: u32, token: u32) -> HandshakePacket { - HandshakePacket { - start_magic: HandshakePacket::HS_MAGIC_SEND_CONV_START, - param1: conv, - param2: token, - data: HandshakePacket::HS_CONNECTION_DATA, - end_magic: HandshakePacket::HS_MAGIC_SEND_CONV_END, - } - } - - pub fn to_bytes(&self) -> Vec { - let mut ret = Vec::with_capacity(std::mem::size_of::()); - - ret.extend_from_slice(&self.start_magic.to_be_bytes()); - ret.extend_from_slice(&self.param1.to_be_bytes()); - ret.extend_from_slice(&self.param2.to_be_bytes()); - ret.extend_from_slice(&self.data.to_be_bytes()); - ret.extend_from_slice(&self.end_magic.to_be_bytes()); - - return ret; - } -} - -impl fmt::Display for HandshakePacket { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "packet") - } -} diff --git a/RustySamovar/src/utils/mod.rs b/RustySamovar/src/utils/mod.rs index ad7572d..1be4997 100644 --- a/RustySamovar/src/utils/mod.rs +++ b/RustySamovar/src/utils/mod.rs @@ -1,15 +1,9 @@ -mod handshake_packet; -mod data_packet; mod id_manager; -mod time_manager; mod avatar_builder; #[macro_use] mod remapper; -pub use self::handshake_packet::HandshakePacket; -pub use self::data_packet::DataPacket; pub use self::id_manager::IdManager; -pub use self::time_manager::TimeManager; pub use self::remapper::Remapper; pub use self::avatar_builder::AvatarBuilder; \ No newline at end of file diff --git a/RustySamovar/src/utils/time_manager.rs b/RustySamovar/src/utils/time_manager.rs deleted file mode 100644 index 2943627..0000000 --- a/RustySamovar/src/utils/time_manager.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::time::SystemTime; -use std::convert::TryInto; - -use chrono::{DateTime, NaiveDateTime, Utc}; -use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; - -pub struct TimeManager { -} - -impl TimeManager { - pub fn duration_since(time_point: SystemTime) -> u64 { - SystemTime::now().duration_since(time_point).unwrap().as_millis().try_into().unwrap() - } - - pub fn timestamp() -> u64 { - return Self::duration_since(SystemTime::UNIX_EPOCH); - } - - pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> std::result::Result, D::Error> { - let time: String = Deserialize::deserialize(deserializer)?; - - if time.is_empty() { - Ok(None) - } else { - Ok(Some(NaiveDateTime::parse_from_str(&time, "%Y-%m-%d %H:%M:%S").map_err(D::Error::custom)?)) - } - } -}