diff --git a/build.rs b/build.rs index 1a9a0bc..cc805ce 100644 --- a/build.rs +++ b/build.rs @@ -36,7 +36,7 @@ fn main() { output_str.push_str(&format!("{name},\n")); } - output_str.push_str(&format!("Unknown,\n")); + output_str.push_str(&format!("Unknown(u16),\n")); // end output_str.push_str("}\n\n"); @@ -56,7 +56,7 @@ fn main() { output_str.push_str(&format!("{key}::{name} => {size},\n")); } - output_str.push_str(&format!("{key}::Unknown => 0,\n")); + output_str.push_str(&format!("{key}::Unknown(_) => 0,\n")); output_str.push_str("}\n\n"); output_str.push_str("}\n\n"); @@ -73,7 +73,7 @@ fn main() { output_str.push_str(&format!("{key}::{name} => \"{name}\",\n")); } - output_str.push_str(&format!("{key}::Unknown => \"Unknown\",\n")); + output_str.push_str(&format!("{key}::Unknown(_) => \"Unknown\",\n")); output_str.push_str("}\n\n"); output_str.push_str("}\n\n"); diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index b7ee68e..c4156f1 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -939,7 +939,9 @@ async fn client_loop( }) .await; } - _ => {}, + ClientZoneIpcData::Unknown { .. } => { + tracing::warn!("Unknown packet {:?} recieved, this should be handled!", data.op_code); + } } } SegmentData::KeepAliveRequest { id, timestamp } => { diff --git a/src/ipc/chat/mod.rs b/src/ipc/chat/mod.rs index a57ff82..f4c7369 100644 --- a/src/ipc/chat/mod.rs +++ b/src/ipc/chat/mod.rs @@ -36,7 +36,7 @@ impl Default for ServerChatIpcSegment { } #[binrw] -#[br(import(magic: &ServerChatIpcType))] +#[br(import(magic: &ServerChatIpcType, _size: &u32))] #[derive(Debug, Clone)] pub enum ServerChatIpcData { /// Sent by the server to Initialize something chat-related? diff --git a/src/ipc/kawari/mod.rs b/src/ipc/kawari/mod.rs index 82057ad..6d15e17 100644 --- a/src/ipc/kawari/mod.rs +++ b/src/ipc/kawari/mod.rs @@ -80,7 +80,7 @@ pub enum CustomIpcType { } #[binrw] -#[br(import(magic: &CustomIpcType))] +#[br(import(magic: &CustomIpcType, _size: &u32))] #[derive(Debug, Clone)] pub enum CustomIpcData { #[br(pre_assert(*magic == CustomIpcType::RequestCreateCharacter))] diff --git a/src/ipc/lobby/mod.rs b/src/ipc/lobby/mod.rs index 814cce7..0d5640d 100644 --- a/src/ipc/lobby/mod.rs +++ b/src/ipc/lobby/mod.rs @@ -83,7 +83,7 @@ impl Default for ServerLobbyIpcSegment { } #[binrw] -#[br(import(magic: &ClientLobbyIpcType))] +#[br(import(magic: &ClientLobbyIpcType, _size: &u32))] #[derive(Debug, Clone)] pub enum ClientLobbyIpcData { /// Sent by the client when it requests the character list in the lobby. @@ -131,7 +131,7 @@ pub enum ClientLobbyIpcData { } #[binrw] -#[br(import(magic: &ServerLobbyIpcType))] +#[br(import(magic: &ServerLobbyIpcType, _size: &u32))] #[derive(Debug, Clone)] pub enum ServerLobbyIpcData { /// Sent by the server to indicate an lobby error occured. diff --git a/src/ipc/zone/mod.rs b/src/ipc/zone/mod.rs index 0ac104d..88d505e 100644 --- a/src/ipc/zone/mod.rs +++ b/src/ipc/zone/mod.rs @@ -167,7 +167,7 @@ pub enum GameMasterCommandType { } #[binrw] -#[br(import(magic: &ServerZoneIpcType))] +#[br(import(magic: &ServerZoneIpcType, _size: &u32))] #[derive(Debug, Clone)] pub enum ServerZoneIpcData { /// Sent by the server as response to ZoneInitRequest. @@ -330,7 +330,7 @@ pub enum ServerZoneIpcData { } #[binrw] -#[br(import(magic: &ClientZoneIpcType))] +#[br(import(magic: &ClientZoneIpcType, size: &u32))] #[derive(Debug, Clone)] pub enum ClientZoneIpcData { /// Sent by the client when they successfully initialize with the server, and they need several bits of information (e.g. what zone to load) @@ -476,7 +476,10 @@ pub enum ClientZoneIpcData { #[brw(pad_after = 8)] unk3: u8, }, - Unknown, + Unknown { + #[br(count = size - 32)] + unk: Vec, + }, } #[cfg(test)] diff --git a/src/packet/encryption.rs b/src/packet/encryption.rs index b0e43d0..ba3860a 100644 --- a/src/packet/encryption.rs +++ b/src/packet/encryption.rs @@ -31,9 +31,9 @@ pub(crate) fn decrypt( blowfish.decrypt(&mut data); let mut cursor = Cursor::new(&data); - T::read_options(&mut cursor, endian, ()) + T::read_options(&mut cursor, endian, (&size,)) } else { - T::read_options(reader, endian, ()) + T::read_options(reader, endian, (&size,)) } } diff --git a/src/packet/ipc.rs b/src/packet/ipc.rs index 0463d21..2fb9efe 100644 --- a/src/packet/ipc.rs +++ b/src/packet/ipc.rs @@ -2,7 +2,7 @@ use binrw::{BinRead, BinWrite, binrw}; /// Required to implement for specializations of `IpcSegment`. These should be read/writeable, however for client packets you can leave calc_size() unimplemented. pub trait ReadWriteIpcSegment: - for<'a> BinRead = ()> + for<'a> BinWrite = ()> + std::fmt::Debug + 'static + for<'a> BinRead = (&'a u32,)> + for<'a> BinWrite = ()> + std::fmt::Debug + 'static { /// Calculate the size of this Ipc segment *including* the 16 byte header. /// When implementing this, please use the size seen in retail instead of guessing. @@ -36,11 +36,12 @@ pub trait ReadWriteIpcSegment: /// ``` #[binrw] #[derive(Debug, Clone)] +#[br(import(size: &u32))] pub struct IpcSegment where for<'a> OpCode: BinRead = ()> + 'a + std::fmt::Debug, for<'a> OpCode: BinWrite = ()> + 'a + std::fmt::Debug, - for<'a> Data: BinRead = (&'a OpCode,)> + 'a + std::fmt::Debug, + for<'a> Data: BinRead = (&'a OpCode, &'a u32)> + 'a + std::fmt::Debug, for<'a> Data: BinWrite = ()> + 'a + std::fmt::Debug, { /// Unknown purpose, but usually 20. @@ -56,6 +57,6 @@ where pub timestamp: u32, /// The data associated with the opcode. #[brw(pad_before = 4)] - #[br(args(&op_code))] + #[br(args(&op_code, size))] pub data: Data, } diff --git a/src/packet/parsing.rs b/src/packet/parsing.rs index d053828..ead260a 100644 --- a/src/packet/parsing.rs +++ b/src/packet/parsing.rs @@ -96,7 +96,10 @@ pub enum SegmentData { KeepAliveResponse { id: u32, timestamp: u32 }, #[br(pre_assert(kind == SegmentType::KawariIpc))] - KawariIpc { data: CustomIpcSegment }, + KawariIpc { + #[br(args(&0))] // this being zero is okay, custom ipc segments don't use the size arg + data: CustomIpcSegment, + }, } impl Default for SegmentData {