From d11c6ad090b428ae6451295c3a31de9d670de821 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Wed, 26 Mar 2025 16:58:55 -0400 Subject: [PATCH] Restore and add the remaining 7.2 opcodes Now Kawari is back to it's full functionality, save for tests being broken and out of date and PlayerSetup has the wrong padding. Success! --- resources/tests/player_spawn.bin | Bin 664 -> 664 bytes src/bin/kawari-world.rs | 9 +++++++ src/packet/ipc.rs | 1 - src/packet/parsing.rs | 6 ++++- src/world/ipc/common_spawn.rs | 4 ++- src/world/ipc/mod.rs | 43 +++++++++++++++++++++++-------- src/world/ipc/player_spawn.rs | 2 +- 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/resources/tests/player_spawn.bin b/resources/tests/player_spawn.bin index 24b6ad3d76fb77dbcf15dec862866c82fc75ccdf..1a9aa3ca0bdd57d2d5cdf288025010a2beba8231 100644 GIT binary patch literal 664 zcmbCLACtp`_xI6Ni)*O?33WchVt7n2$YOm@hGfi;ulUhA*)b zh~2pP*kSk@kj=`?!_Jt-fRrZ0E$p3LEKN;?Yz&R9QOt&LI2ahC_?ee67_hS^8?v)7 UFflPQ$ff{O1-r9ENeNH*gaH^C8TFW$su&nLlYl9SsgsqJp?M_( KLkc4+vN-^o(=uWJ diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 0ea46cf..4c3a132 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -755,6 +755,15 @@ async fn main() { ClientZoneIpcData::Unk15 { .. } => { tracing::info!("Recieved Unk15!"); } + ClientZoneIpcData::Unk16 { .. } => { + tracing::info!("Recieved Unk16!"); + } + ClientZoneIpcData::Unk17 { .. } => { + tracing::info!("Recieved Unk17!"); + } + ClientZoneIpcData::Unk18 { .. } => { + tracing::info!("Recieved Unk18!"); + } } } SegmentType::KeepAlive { id, timestamp } => { diff --git a/src/packet/ipc.rs b/src/packet/ipc.rs index 47c02df..fc41db1 100644 --- a/src/packet/ipc.rs +++ b/src/packet/ipc.rs @@ -45,7 +45,6 @@ where /// Unknown purpose, but usually 0. pub unk2: u8, /// The opcode for this segment. - #[br(dbg)] pub op_code: OpCode, #[brw(pad_before = 2)] // empty /// Unknown purpose, but safe to keep 0. diff --git a/src/packet/parsing.rs b/src/packet/parsing.rs index 53e9d32..79128a1 100644 --- a/src/packet/parsing.rs +++ b/src/packet/parsing.rs @@ -255,7 +255,11 @@ mod tests { type ClientLobbyIpcSegment = IpcSegment; - impl ReadWriteIpcSegment for ClientLobbyIpcSegment {} + impl ReadWriteIpcSegment for ClientLobbyIpcSegment { + fn calc_size(&self) -> u32 { + todo!() + } + } let packet_types = [ SegmentType::InitializeEncryption { diff --git a/src/world/ipc/common_spawn.rs b/src/world/ipc/common_spawn.rs index 52c7c2a..2ce37f8 100644 --- a/src/world/ipc/common_spawn.rs +++ b/src/world/ipc/common_spawn.rs @@ -172,6 +172,8 @@ pub struct CommonSpawn { pub u24: u8, // assumed pub u25: u8, // assumed pub u26: u8, // assumed + pub u27: u8, // assumed + pub u28: u8, // assumed /// Must be unique for each actor. pub spawn_index: u8, #[brw(pad_size_to = 2)] // for modes that don't have a param @@ -193,7 +195,7 @@ pub struct CommonSpawn { pub mount_color: u8, pub scale: u8, pub element_data: [u8; 6], - pub padding2: [u8; 1], + pub padding2: [u8; 3], pub effect: [StatusEffect; 30], pub pos: Position, pub models: [u32; 10], diff --git a/src/world/ipc/mod.rs b/src/world/ipc/mod.rs index 587b100..bc6deb1 100644 --- a/src/world/ipc/mod.rs +++ b/src/world/ipc/mod.rs @@ -78,14 +78,17 @@ impl ReadWriteIpcSegment for ClientZoneIpcSegment { ClientZoneIpcType::UpdatePositionHandler => 24, ClientZoneIpcType::LogOut => 8, ClientZoneIpcType::Disconnected => 8, - ClientZoneIpcType::ChatMessage => todo!(), - ClientZoneIpcType::GameMasterCommand => todo!(), + ClientZoneIpcType::ChatMessage => 1056, + ClientZoneIpcType::GameMasterCommand => 32, ClientZoneIpcType::Unk12 => todo!(), - ClientZoneIpcType::EnterZoneLine => todo!(), + ClientZoneIpcType::EnterZoneLine => 24, ClientZoneIpcType::Unk13 => todo!(), ClientZoneIpcType::Unk14 => todo!(), - ClientZoneIpcType::ActionRequest => todo!(), + ClientZoneIpcType::ActionRequest => 32, ClientZoneIpcType::Unk15 => todo!(), + ClientZoneIpcType::Unk16 => 6, + ClientZoneIpcType::Unk17 => 32, + ClientZoneIpcType::Unk18 => 8, } } } @@ -116,7 +119,7 @@ impl ReadWriteIpcSegment for ServerZoneIpcSegment { ServerZoneIpcType::PlayerStats => 224, ServerZoneIpcType::PlayerSetup => 2784, ServerZoneIpcType::UpdateClassInfo => 48, - ServerZoneIpcType::PlayerSpawn => 656, + ServerZoneIpcType::PlayerSpawn => 664, ServerZoneIpcType::InitResponse => 16, ServerZoneIpcType::LogOutComplete => 8, ServerZoneIpcType::ActorSetPos => 24, @@ -225,7 +228,7 @@ pub enum ServerZoneIpcType { // Sent by the server to spawn an NPC NpcSpawn = 0x13F, // Sent by the server to update an actor's status effect list - StatusEffectList = 0xBB, + StatusEffectList = 0x347, // Sent by the server when it's time to change the weather WeatherChange = 0x175, // Sent to inform the client of an inventory item @@ -259,26 +262,32 @@ pub enum ClientZoneIpcType { Unk7 = 0x2B5, UpdatePositionHandler = 0x231, // Sent by the client when the user requests to log out - LogOut = 0x217, + LogOut = 0x21A, // Sent by the client when it's actually disconnecting Disconnected = 0x360, // Sent by the client when they send a chat message - ChatMessage = 0xCA, + ChatMessage = 0x177, // Sent by the client when they send a GM command. This can only be sent by the client if they are sent a GM rank. - GameMasterCommand = 0x3B3, + GameMasterCommand = 0x389, // Unknown, client sends this for ??? Unk12 = 0x0E9, // Sent by the client when the character walks into a zone transistion - EnterZoneLine = 0x205, + EnterZoneLine = 0x1BF, // Sent by the client after we sent a InitZone in TravelToZone?? // TODO: Actually, I don't think is real... Unk13 = 0x2EE, // Sent by the client for unknown reasons Unk14 = 0x87, // Sent by the client when a character performs an action - ActionRequest = 0x213, + ActionRequest = 0x361, /// Sent by the client for unknown reasons, it's a bunch of numbers? Unk15 = 0x10B, + /// 8 unknown bytes sent by the client for unknown reason + Unk16 = 0x188, + // FIXME: 32 bytes of something from the client, not sure what yet + Unk17 = 0x1D2, + // FIXME: 8 bytes of something from the client, not sure what yet + Unk18 = 0xDD, } #[binrw] @@ -456,6 +465,18 @@ pub enum ClientZoneIpcData { ActionRequest(ActionRequest), #[br(pre_assert(*magic == ClientZoneIpcType::Unk15))] Unk15 { unk: [u8; 632] }, + #[br(pre_assert(*magic == ClientZoneIpcType::Unk16))] + Unk16 { + unk: [u8; 8], // TODO: unknown + }, + #[br(pre_assert(*magic == ClientZoneIpcType::Unk17))] + Unk17 { + unk: [u8; 32], // TODO: unknown + }, + #[br(pre_assert(*magic == ClientZoneIpcType::Unk18))] + Unk18 { + unk: [u8; 8], // TODO: unknown + }, } #[cfg(test)] diff --git a/src/world/ipc/player_spawn.rs b/src/world/ipc/player_spawn.rs index ee0eb17..2fc0b96 100644 --- a/src/world/ipc/player_spawn.rs +++ b/src/world/ipc/player_spawn.rs @@ -30,7 +30,7 @@ pub struct PlayerSpawn { pub common: CommonSpawn, - pub padding: [u8; 2], + pub padding: [u8; 6], } #[cfg(test)]