From 45be3835bb3d9a03aa5cdf50221a24dcd01ae502 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 13 Mar 2025 21:49:03 -0400 Subject: [PATCH] Add more init IPC packets This doesn't improve the loading situation unfortunately, but I guess it's more "correct". Unk7/Unk11 is still a complete mystery to me, though. --- src/bin/kawari-world.rs | 138 +++++++++++++++++++++++++++++++++++++++- src/ipc.rs | 35 +++++++++- 2 files changed, 170 insertions(+), 3 deletions(-) diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 44b75ca..60f3b19 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -320,6 +320,110 @@ async fn main() { .await; } + // unk10 + { + let ipc = IPCSegment { + unk1: 0, + unk2: 0, + op_code: IPCOpCode::Unk10, + server_id: 69, // lol + timestamp: timestamp_secs(), + data: IPCStructData::Unk10 { + unk: 0x41a0000000000002, + }, + }; + + let response_packet = PacketSegment { + source_actor: state.player_id.unwrap(), + target_actor: state.player_id.unwrap(), + segment_type: SegmentType::Ipc { data: ipc }, + }; + send_packet( + &mut write, + &[response_packet], + &mut state, + CompressionType::Oodle, + ) + .await; + } + + // unk9 + { + let ipc = IPCSegment { + unk1: 0, + unk2: 0, + op_code: IPCOpCode::Unk9, + server_id: 69, // lol + timestamp: timestamp_secs(), + data: IPCStructData::Unk9 { unk: [0; 24] }, + }; + + let response_packet = PacketSegment { + source_actor: state.player_id.unwrap(), + target_actor: state.player_id.unwrap(), + segment_type: SegmentType::Ipc { data: ipc }, + }; + send_packet( + &mut write, + &[response_packet], + &mut state, + CompressionType::Oodle, + ) + .await; + } + + // link shell information + { + let ipc = IPCSegment { + unk1: 0, + unk2: 0, + op_code: IPCOpCode::LinkShellInformation, + server_id: 69, // lol + timestamp: timestamp_secs(), + data: IPCStructData::LinkShellInformation { + unk: [0; 456], + }, + }; + + let response_packet = PacketSegment { + source_actor: state.player_id.unwrap(), + target_actor: state.player_id.unwrap(), + segment_type: SegmentType::Ipc { data: ipc }, + }; + send_packet( + &mut write, + &[response_packet], + &mut state, + CompressionType::Oodle, + ) + .await; + } + + // unk8 + { + let ipc = IPCSegment { + unk1: 0, + unk2: 0, + op_code: IPCOpCode::Unk8, + server_id: 69, // lol + timestamp: timestamp_secs(), + data: IPCStructData::Unk8 { unk: [0; 808] }, + }; + + let response_packet = PacketSegment { + source_actor: state.player_id.unwrap(), + target_actor: state.player_id.unwrap(), + segment_type: SegmentType::Ipc { data: ipc }, + }; + send_packet( + &mut write, + &[response_packet], + &mut state, + CompressionType::Oodle, + ) + .await; + } + // Init Zone { let ipc = IPCSegment { @@ -472,8 +576,38 @@ async fn main() { IPCStructData::Unk6 { .. } => { tracing::info!("Recieved Unk6!"); } - IPCStructData::Unk7 { .. } => { - tracing::info!("Recieved Unk7!"); + IPCStructData::Unk7 { + timestamp, unk1, .. + } => { + tracing::info!("Recieved Unk7! {:#?}", unk1); + + // send unk11 in response + { + let ipc = IPCSegment { + unk1: 0, + unk2: 0, + op_code: IPCOpCode::Unk11, + server_id: 0, + timestamp: timestamp_secs(), + data: IPCStructData::Unk11 { + timestamp: *timestamp, + unk: 333, + }, + }; + + let response_packet = PacketSegment { + source_actor: state.player_id.unwrap(), + target_actor: state.player_id.unwrap(), + segment_type: SegmentType::Ipc { data: ipc }, + }; + send_packet( + &mut write, + &[response_packet], + &mut state, + CompressionType::Oodle, + ) + .await; + } } IPCStructData::UpdatePositionHandler { .. } => { tracing::info!("Recieved UpdatePositionHandler!"); diff --git a/src/ipc.rs b/src/ipc.rs index 8607c44..3d344ff 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -85,6 +85,17 @@ pub enum IPCOpCode { ActorSetPos = 0x223, // Sent by the server when they send a chat message ServerChatMessage = 0x196, + // Unknown, server sends to the client before player spawn + Unk8 = 0x134, + // Unknown, but seems to contain information on cross-world linkshells + LinkShellInformation = 0x234, + // Unknown, server sends to the client before player spawn + Unk9 = 0x189, + // Unknown, server sends to the client before player spawn. + // Seems to the same across two different characters? + Unk10 = 0x110, + // Unknown, server sends this in response to Unk7 + Unk11 = 0x156, } #[binrw] @@ -283,7 +294,10 @@ pub enum IPCStructData { #[br(pre_assert(*magic == IPCOpCode::Unk7))] Unk7 { // TODO: full of possibly interesting information - unk: [u8; 32], + timestamp: u32, + #[brw(pad_before = 8)] // empty bytes + #[brw(pad_after = 4)] // empty bytes + unk1: [u8; 16], // something }, #[br(pre_assert(*magic == IPCOpCode::UpdatePositionHandler))] UpdatePositionHandler { @@ -441,6 +455,20 @@ pub enum IPCStructData { #[bw(map = write_string)] message: String, }, + #[br(pre_assert(false))] + Unk8 { unk: [u8; 808] }, + #[br(pre_assert(false))] + LinkShellInformation { unk: [u8; 456] }, + #[br(pre_assert(false))] + Unk9 { unk: [u8; 24] }, + #[br(pre_assert(false))] + Unk10 { unk: u64 }, + #[br(pre_assert(false))] + Unk11 { + timestamp: u32, + #[brw(pad_after = 24)] // empty bytes + unk: u32, + }, } #[binrw] @@ -500,6 +528,11 @@ impl IPCSegment { IPCStructData::GameMasterCommand { .. } => todo!(), IPCStructData::ActorSetPos { .. } => 24, IPCStructData::ServerChatMessage { .. } => 776, + IPCStructData::Unk8 { .. } => 808, + IPCStructData::LinkShellInformation { .. } => 456, + IPCStructData::Unk9 { .. } => 24, + IPCStructData::Unk10 { .. } => 8, + IPCStructData::Unk11 { .. } => 32, } } }