diff --git a/src/bin/kawari-lobby.rs b/src/bin/kawari-lobby.rs index c30b294..275e601 100644 --- a/src/bin/kawari-lobby.rs +++ b/src/bin/kawari-lobby.rs @@ -303,7 +303,8 @@ async fn main() { .. } => { connection.selected_service_account = Some( - connection.service_accounts[*account_index as usize].id, + connection.service_accounts[*account_index as usize].id + as u32, ); connection.send_lobby_info(*sequence).await } diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 7e835e1..610ea2d 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -154,9 +154,9 @@ async fn client_loop( for segment in &segments { match &segment.data { SegmentData::None() => {}, - SegmentData::Setup { ticket } => { + SegmentData::Setup { actor_id } => { // for some reason they send a string representation - let actor_id = ticket.parse::().unwrap(); + let actor_id = actor_id.parse::().unwrap(); // initialize player data if it doesn't exist' if connection.player_data.actor_id == 0 { @@ -193,7 +193,7 @@ async fn client_loop( connection.send_chat_segment(PacketSegment { segment_type: SegmentType::Initialize, data: SegmentData::Initialize { - player_id: connection.player_data.actor_id, + actor_id: connection.player_data.actor_id, timestamp: timestamp_secs(), }, ..Default::default() diff --git a/src/ipc/lobby/login_reply.rs b/src/ipc/lobby/login_reply.rs index 849ce2c..b2eaca2 100644 --- a/src/ipc/lobby/login_reply.rs +++ b/src/ipc/lobby/login_reply.rs @@ -6,8 +6,7 @@ use crate::common::{read_string, write_string}; #[binrw] #[derive(Debug, Clone, Default, Deserialize, Serialize)] pub struct ServiceAccount { - pub id: u32, - pub unk1: u32, + pub id: u64, pub index: u32, #[bw(pad_size_to = 0x44)] #[br(count = 0x44)] diff --git a/src/ipc/lobby/mod.rs b/src/ipc/lobby/mod.rs index 9260dec..b72485f 100644 --- a/src/ipc/lobby/mod.rs +++ b/src/ipc/lobby/mod.rs @@ -103,7 +103,8 @@ pub enum ClientLobbyIpcData { unk1: u8, unk2: u16, unk3: u32, // TODO: probably multiple params - account_id: u64, + account_id: u32, + unk4: u32, }, /// Sent by the client when it requests to enter a world. #[br(pre_assert(*magic == ClientLobbyIpcType::GameLogin))] @@ -111,8 +112,10 @@ pub enum ClientLobbyIpcData { sequence: u64, content_id: u64, // TODO: what else is in here? - unk1: u64, - unk2: u64, + unk1: u32, + unk2: u32, + unk3: u32, + unk4: u32, }, /// Sent by the client after exchanging encryption information with the lobby server. #[br(pre_assert(*magic == ClientLobbyIpcType::LoginEx))] @@ -304,6 +307,7 @@ mod tests { unk2: 0, account_id: 0, unk3: 0, + unk4: 0, }, ), ( @@ -313,6 +317,8 @@ mod tests { content_id: 0, unk1: 0, unk2: 0, + unk3: 0, + unk4: 0, }, ), ( diff --git a/src/ipc/lobby/service_login_reply.rs b/src/ipc/lobby/service_login_reply.rs index 21bf0a5..25f20a4 100644 --- a/src/ipc/lobby/service_login_reply.rs +++ b/src/ipc/lobby/service_login_reply.rs @@ -36,8 +36,7 @@ impl Default for CharacterFlag { #[binrw] #[derive(Debug, Clone, Default)] pub struct CharacterDetails { - #[brw(pad_after = 4)] - pub actor_id: u32, + pub player_id: u64, pub content_id: u64, pub index: u8, pub flags: CharacterFlag, diff --git a/src/ipc/zone/mod.rs b/src/ipc/zone/mod.rs index d94150e..e44cc3c 100644 --- a/src/ipc/zone/mod.rs +++ b/src/ipc/zone/mod.rs @@ -128,7 +128,10 @@ impl Default for ClientZoneIpcSegment { op_code: ClientZoneIpcType::InitRequest, option: 0, timestamp: 0, - data: ClientZoneIpcData::InitRequest { unk: [0; 120] }, + data: ClientZoneIpcData::InitRequest { + unk1: String::default(), + unk2: String::default(), + }, } } } @@ -472,8 +475,17 @@ 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) #[br(pre_assert(*magic == ClientZoneIpcType::InitRequest))] InitRequest { - // TODO: full of possibly interesting information - unk: [u8; 120], + #[brw(pad_before = 40)] // seems to be empty? + #[brw(pad_size_to = 32)] + #[br(count = 32)] + #[br(map = read_string)] + #[bw(map = write_string)] + unk1: String, + #[br(count = 48)] + #[brw(pad_size_to = 48)] + #[br(map = read_string)] + #[bw(map = write_string)] + unk2: String, }, /// Sent by the client when they're done loading and they need to be spawned in #[br(pre_assert(*magic == ClientZoneIpcType::FinishLoading))] @@ -952,7 +964,10 @@ mod tests { let ipc_types = [ ( ClientZoneIpcType::InitRequest, - ClientZoneIpcData::InitRequest { unk: [0; 120] }, + ClientZoneIpcData::InitRequest { + unk1: String::default(), + unk2: String::default(), + }, ), ( ClientZoneIpcType::FinishLoading, diff --git a/src/lobby/connection.rs b/src/lobby/connection.rs index 1c8f5d2..fa37fb8 100644 --- a/src/lobby/connection.rs +++ b/src/lobby/connection.rs @@ -412,7 +412,7 @@ impl LobbyConnection { unk2: 0x1, action: LobbyCharacterActionKind::Create, details: CharacterDetails { - actor_id: our_actor_id, + player_id: our_actor_id as u64, // TODO: not correct content_id: our_content_id, character_name: character_action.name.clone(), origin_server_name: self.world_name.clone(), @@ -458,7 +458,7 @@ impl LobbyConnection { unk2: 0x1, action: LobbyCharacterActionKind::Delete, details: CharacterDetails { - actor_id: 0, // TODO: fill maybe? + player_id: 0, // TODO: fill maybe? content_id: character_action.content_id, character_name: character_action.name.clone(), origin_server_name: self.world_name.clone(), @@ -506,7 +506,7 @@ impl LobbyConnection { unk2: 0x1, action: LobbyCharacterActionKind::RemakeChara, details: CharacterDetails { - actor_id: 0, // TODO: fill maybe? + player_id: 0, // TODO: fill maybe? content_id: character_action.content_id, character_name: character_action.name.clone(), origin_server_name: self.world_name.clone(), diff --git a/src/login/database.rs b/src/login/database.rs index 1932da0..847645a 100644 --- a/src/login/database.rs +++ b/src/login/database.rs @@ -166,7 +166,6 @@ impl LoginDatabase { for (index, id) in accounts.enumerate() { service_accounts.push(ServiceAccount { id: id.unwrap(), - unk1: 0, index: index as u32, name: format!("FINAL FANTASY XIV {}", index + 1), // TODO: don't add the "1" if you only have one service account }); diff --git a/src/packet/parsing.rs b/src/packet/parsing.rs index 4b8f7d1..ec2321a 100644 --- a/src/packet/parsing.rs +++ b/src/packet/parsing.rs @@ -57,11 +57,11 @@ pub enum SegmentData { #[br(count = 36)] #[br(map = read_string)] #[bw(map = write_string)] - ticket: String, // square enix in their infinite wisdom has this as a STRING REPRESENTATION of an integer. what + actor_id: String, // square enix in their infinite wisdom has this as a STRING REPRESENTATION of an integer. what }, #[br(pre_assert(kind == SegmentType::Initialize))] Initialize { - player_id: u32, + actor_id: u32, #[brw(pad_after = 32)] timestamp: u32, }, diff --git a/src/world/connection.rs b/src/world/connection.rs index 681c1a9..8964d70 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -199,7 +199,7 @@ impl ZoneConnection { self.send_segment(PacketSegment { segment_type: SegmentType::Initialize, data: SegmentData::Initialize { - player_id: self.player_data.actor_id, + actor_id: self.player_data.actor_id, timestamp: timestamp_secs(), }, ..Default::default() diff --git a/src/world/database.rs b/src/world/database.rs index de3d5c2..d03e527 100644 --- a/src/world/database.rs +++ b/src/world/database.rs @@ -447,7 +447,7 @@ impl WorldDatabase { }; characters.push(CharacterDetails { - actor_id: *actor_id, + player_id: *actor_id as u64, // TODO: not correct content_id: *content_id as u64, index: index as u8, flags: CharacterFlag::NONE,