From b426de677f833746764fcca0fd36bb08c49643f2 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 1 May 2025 23:34:06 -0400 Subject: [PATCH] Begin separating chat IPC, fix tests --- resources/opcodes.json | 12 ++++++---- src/world/chat.rs | 40 +++++++++++++++++++++++++++++++ src/world/connection.rs | 14 +++++++---- src/world/ipc/init_zone.rs | 4 +++- src/world/ipc/inventory_modify.rs | 2 +- src/world/ipc/mod.rs | 32 ++++++++++--------------- src/world/mod.rs | 2 ++ 7 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 src/world/chat.rs diff --git a/resources/opcodes.json b/resources/opcodes.json index e5e4821..fba615b 100644 --- a/resources/opcodes.json +++ b/resources/opcodes.json @@ -1,10 +1,5 @@ { "ServerZoneIpcType": [ - { - "name": "InitializeChat", - "opcode": 2, - "size": 8 - }, { "name": "InitZone", "opcode": 790, @@ -273,6 +268,13 @@ "size": 48 } ], + "ServerChatIpcType": [ + { + "name": "LoginReply", + "opcode": 2, + "size": 8 + } + ], "ServerLobbyIpcType": [ { "name": "NackReply", diff --git a/src/world/chat.rs b/src/world/chat.rs new file mode 100644 index 0000000..d0581ed --- /dev/null +++ b/src/world/chat.rs @@ -0,0 +1,40 @@ +use binrw::binrw; + +use crate::{ + opcodes::ServerChatIpcType, + packet::{IpcSegment, ReadWriteIpcSegment}, +}; + +pub type ServerChatIpcSegment = IpcSegment; + +impl ReadWriteIpcSegment for ServerChatIpcSegment { + fn calc_size(&self) -> u32 { + // 16 is the size of the IPC header + 16 + self.op_code.calc_size() + } +} + +// TODO: make generic +impl Default for ServerChatIpcSegment { + fn default() -> Self { + Self { + unk1: 0x14, + unk2: 0, + op_code: ServerChatIpcType::LoginReply, + server_id: 0, + timestamp: 0, + data: ServerChatIpcData::LoginReply { + timestamp: 0, + sid: 0, + }, + } + } +} + +#[binrw] +#[br(import(_magic: &ServerChatIpcType))] +#[derive(Debug, Clone)] +pub enum ServerChatIpcData { + /// Sent by the server to Initialize something chat-related? + LoginReply { timestamp: u32, sid: u32 }, +} diff --git a/src/world/connection.rs b/src/world/connection.rs index 9155b93..ff919a9 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -12,11 +12,12 @@ use crate::{ OBFUSCATION_ENABLED_MODE, common::{GameData, ObjectId, Position, timestamp_secs}, config::get_config, - opcodes::ServerZoneIpcType, + opcodes::{ServerChatIpcType, ServerZoneIpcType}, packet::{ CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType, parse_packet, send_packet, }, + world::chat::{ServerChatIpcData, ServerChatIpcSegment}, }; use super::{ @@ -169,7 +170,7 @@ impl ZoneConnection { .await; } - pub async fn send_chat_segment(&mut self, segment: PacketSegment) { + pub async fn send_chat_segment(&mut self, segment: PacketSegment) { send_packet( &mut self.socket, &mut self.state, @@ -248,10 +249,13 @@ impl ZoneConnection { assert!(self.player_data.actor_id != 0); { - let ipc = ServerZoneIpcSegment { - op_code: ServerZoneIpcType::InitializeChat, + let ipc = ServerChatIpcSegment { + op_code: ServerChatIpcType::LoginReply, timestamp: timestamp_secs(), - data: ServerZoneIpcData::InitializeChat { unk: [0; 8] }, + data: ServerChatIpcData::LoginReply { + timestamp: 0, + sid: 0, + }, ..Default::default() }; diff --git a/src/world/ipc/init_zone.rs b/src/world/ipc/init_zone.rs index b897687..0647958 100644 --- a/src/world/ipc/init_zone.rs +++ b/src/world/ipc/init_zone.rs @@ -49,7 +49,9 @@ mod tests { let mut buffer = Cursor::new(&buffer); let init_zone = InitZone::read_le(&mut buffer).unwrap(); - assert_eq!(init_zone.zone_id, 182); + assert_eq!(init_zone.zone_id, 1); + assert_eq!(init_zone.territory_type, 182); + assert_eq!(init_zone.territory_index, 0); assert_eq!(init_zone.weather_id, 2); assert_eq!(init_zone.position.x, 40.519722); assert_eq!(init_zone.position.y, 4.0); diff --git a/src/world/ipc/inventory_modify.rs b/src/world/ipc/inventory_modify.rs index 1e08595..a102e23 100644 --- a/src/world/ipc/inventory_modify.rs +++ b/src/world/ipc/inventory_modify.rs @@ -44,7 +44,7 @@ mod tests { let modify_inventory = InventoryModify::read_le(&mut buffer).unwrap(); assert_eq!(modify_inventory.context_id, 0x10000000); - assert_eq!(modify_inventory.operation_type, 128); + assert_eq!(modify_inventory.operation_type, 60); assert_eq!(modify_inventory.src_actor_id, 0); assert_eq!(modify_inventory.src_storage_id, ContainerType::Equipped); assert_eq!(modify_inventory.src_container_index, 3); diff --git a/src/world/ipc/mod.rs b/src/world/ipc/mod.rs index 3527df3..c6880e7 100644 --- a/src/world/ipc/mod.rs +++ b/src/world/ipc/mod.rs @@ -122,10 +122,10 @@ impl Default for ServerZoneIpcSegment { Self { unk1: 0x14, unk2: 0, - op_code: ServerZoneIpcType::InitializeChat, + op_code: ServerZoneIpcType::InitZone, server_id: 0, timestamp: 0, - data: ServerZoneIpcData::InitializeChat { unk: [0; 8] }, + data: ServerZoneIpcData::InitZone(InitZone::default()), } } } @@ -146,8 +146,6 @@ pub enum GameMasterCommandType { #[br(import(_magic: &ServerZoneIpcType))] #[derive(Debug, Clone)] pub enum ServerZoneIpcData { - /// Sent by the server to Initialize something chat-related? - InitializeChat { unk: [u8; 8] }, /// Sent by the server as response to ZoneInitRequest. InitResponse { unk1: u64, @@ -371,10 +369,6 @@ mod tests { #[test] fn world_ipc_sizes() { let ipc_types = [ - ( - ServerZoneIpcType::InitializeChat, - ServerZoneIpcData::InitializeChat { unk: [0; 8] }, - ), ( ServerZoneIpcType::InitResponse, ServerZoneIpcData::InitResponse { @@ -396,8 +390,8 @@ mod tests { ServerZoneIpcData::PlayerStats(PlayerStats::default()), ), ( - ServerZoneIpcType::PlayerSetup, - ServerZoneIpcData::PlayerSetup(PlayerSetup::default()), + ServerZoneIpcType::PlayerStatus, + ServerZoneIpcData::PlayerStatus(PlayerSetup::default()), ), ( ServerZoneIpcType::UpdateClassInfo, @@ -412,8 +406,8 @@ mod tests { ServerZoneIpcData::LogOutComplete { unk: [0; 8] }, ), ( - ServerZoneIpcType::ActorSetPos, - ServerZoneIpcData::ActorSetPos(ActorSetPos::default()), + ServerZoneIpcType::Warp, + ServerZoneIpcData::Warp(ActorSetPos::default()), ), ( ServerZoneIpcType::ServerChatMessage, @@ -432,7 +426,7 @@ mod tests { ), ( ServerZoneIpcType::Move, - ServerZoneIpcData::ActorMove(ActorMove::default()), + ServerZoneIpcData::Move(ActorMove::default()), ), ( ServerZoneIpcType::NpcSpawn, @@ -443,20 +437,20 @@ mod tests { ServerZoneIpcData::StatusEffectList(StatusEffectList::default()), ), ( - ServerZoneIpcType::WeatherChange, - ServerZoneIpcData::WeatherChange(WeatherChange::default()), + ServerZoneIpcType::WeatherId, + ServerZoneIpcData::WeatherId(WeatherChange::default()), ), ( - ServerZoneIpcType::ItemInfo, - ServerZoneIpcData::ItemInfo(ItemInfo::default()), + ServerZoneIpcType::UpdateItem, + ServerZoneIpcData::UpdateItem(ItemInfo::default()), ), ( ServerZoneIpcType::ContainerInfo, ServerZoneIpcData::ContainerInfo(ContainerInfo::default()), ), ( - ServerZoneIpcType::EventPlay, - ServerZoneIpcData::EventPlay(EventPlay::default()), + ServerZoneIpcType::EventScene, + ServerZoneIpcData::EventScene(EventPlay::default()), ), ( ServerZoneIpcType::EventStart, diff --git a/src/world/mod.rs b/src/world/mod.rs index 9bb7e2e..462f818 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -28,3 +28,5 @@ pub use actor::Actor; mod status_effects; pub use status_effects::StatusEffects; + +pub mod chat;