diff --git a/run.sh b/run.sh index 5fe4b3a..046e145 100755 --- a/run.sh +++ b/run.sh @@ -8,4 +8,5 @@ cargo run -q --package kawari --bin kawari-login & cargo run -q --package kawari --bin kawari-patch & cargo run -q --package kawari --bin kawari-web & cargo run -q --package kawari --bin kawari-lobby & +cargo run -q --package kawari --bin kawari-world & wait diff --git a/src/bin/kawari-lobby.rs b/src/bin/kawari-lobby.rs index 7a49810..8eb5ded 100644 --- a/src/bin/kawari-lobby.rs +++ b/src/bin/kawari-lobby.rs @@ -1,5 +1,4 @@ use std::cmp::min; -use std::fs::read; use std::time::{SystemTime, UNIX_EPOCH}; use kawari::client_select_data::{ClientCustomizeData, ClientSelectData}; @@ -23,7 +22,10 @@ async fn main() { let (socket, _) = listener.accept().await.unwrap(); let (mut read, mut write) = tokio::io::split(socket); - let mut state = State {client_key:None, session_id: None }; + let mut state = State { + client_key: None, + session_id: None, + }; tokio::spawn(async move { let mut buf = [0; 2056]; @@ -77,7 +79,8 @@ async fn main() { } => { tracing::info!("Client is joining the world..."); - send_enter_world(&mut write, &state, *sequence, *lookup_id).await; + send_enter_world(&mut write, &state, *sequence, *lookup_id) + .await; } _ => { panic!("The server is recieving a IPC response packet!") @@ -131,7 +134,7 @@ async fn send_account_list(socket: &mut WriteHalf, state: &State) { .unwrap(); // send the client the service account list - let mut service_accounts = [ServiceAccount { + let service_accounts = [ServiceAccount { id: 0x002E4A2B, unk1: 0, index: 0, diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs new file mode 100644 index 0000000..b485142 --- /dev/null +++ b/src/bin/kawari-world.rs @@ -0,0 +1,46 @@ +use kawari::packet::{SegmentType, State, parse_packet, send_keep_alive}; +use tokio::io::AsyncReadExt; +use tokio::net::TcpListener; + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + + let listener = TcpListener::bind("127.0.0.1:7100").await.unwrap(); + + tracing::info!("World server started on 7100"); + + loop { + let (socket, _) = listener.accept().await.unwrap(); + let (mut read, mut write) = tokio::io::split(socket); + + let mut state = State { + client_key: None, + session_id: None, + }; + + tokio::spawn(async move { + let mut buf = [0; 2056]; + loop { + let n = read.read(&mut buf).await.expect("Failed to read data!"); + + if n != 0 { + let segments = parse_packet(&buf[..n], &mut state).await; + for segment in &segments { + match &segment.segment_type { + SegmentType::Ipc { data } => { + panic!("The server is recieving a IPC response or unknown packet!") + } + SegmentType::KeepAlive { id, timestamp } => { + send_keep_alive(&mut write, &state, *id, *timestamp).await + } + _ => { + panic!("The server is recieving a response or unknown packet!") + } + } + } + } + } + }); + } +} diff --git a/src/encryption.rs b/src/encryption.rs index ab88794..1ba051c 100644 --- a/src/encryption.rs +++ b/src/encryption.rs @@ -49,7 +49,7 @@ where let decryption_result = blowfish_decode(encryption_key.as_ptr(), 16, data.as_ptr(), size); let decrypted_data = slice::from_raw_parts(decryption_result, size as usize); - write("decrypted.bin", &decrypted_data).unwrap(); + write("decrypted.bin", decrypted_data).unwrap(); let mut cursor = Cursor::new(&decrypted_data); T::read_options(&mut cursor, endian, ()) diff --git a/src/packet.rs b/src/packet.rs index 5af9586..be75c17 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -11,7 +11,7 @@ use tokio::{ }; use crate::{ - common::{read_bool_from, read_string, write_bool_as}, + common::read_string, encryption::{decrypt, encrypt}, ipc::IPCSegment, }; @@ -61,6 +61,15 @@ pub enum SegmentType { KeepAliveResponse { id: u32, timestamp: u32 }, } +#[binrw] +#[brw(repr = u8)] +#[derive(Debug)] +enum CompressionType { + Uncompressed = 0, + ZLib = 1, + Oodle = 2, +} + #[binrw] #[derive(Debug)] struct PacketHeader { @@ -71,9 +80,7 @@ struct PacketHeader { connection_type: ConnectionType, segment_count: u16, unk3: u8, - #[br(map = read_bool_from::)] - #[bw(map = write_bool_as::)] - compressed: bool, + compressed: CompressionType, unk4: u16, unk5: u32, // iolite says the size after oodle decompression } @@ -108,6 +115,7 @@ impl PacketSegment { #[brw(import(encryption_key: Option<&[u8]>))] #[derive(Debug)] struct Packet { + #[br(dbg)] header: PacketHeader, #[br(count = header.segment_count, args { inner: (encryption_key,) })] #[bw(args(encryption_key))] @@ -144,7 +152,7 @@ pub async fn send_packet( connection_type: ConnectionType::Lobby, segment_count: segments.len() as u16, unk3: 0, - compressed: false, + compressed: CompressionType::Uncompressed, unk4: 0, unk5: 0, };