From 67ec72a962aed5ed0ca42f9b51036b2421405e81 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 1 May 2025 22:45:49 -0400 Subject: [PATCH] Rename the remaining lobby IPC opcodes, reorder them too --- resources/opcodes.json | 32 +++++----- src/bin/kawari-lobby.rs | 2 +- src/lobby/connection.rs | 53 +++++++++-------- src/lobby/ipc/mod.rs | 126 ++++++++++++++++++++-------------------- 4 files changed, 106 insertions(+), 107 deletions(-) diff --git a/resources/opcodes.json b/resources/opcodes.json index f89e34f..43222f6 100644 --- a/resources/opcodes.json +++ b/resources/opcodes.json @@ -275,39 +275,39 @@ ], "ServerLobbyIpcType": [ { - "name": "LobbyError", + "name": "NackReply", "opcode": 2, "size": 536 }, { - "name": "LobbyServiceAccountList", + "name": "LoginReply", "opcode": 12, "size": 656 }, { - "name": "LobbyCharacterList", + "name": "ServiceLoginReply", "opcode": 13, "size": 2472 }, { - "name": "LobbyEnterWorld", + "name": "CharaMakeReply", + "opcode": 14, + "size": 2568 + }, + { + "name": "GameLoginReply", "opcode": 15, "size": 160 }, { - "name": "LobbyServerList", + "name": "DistWorldInfo", "opcode": 21, "size": 528 }, { - "name": "LobbyRetainerList", + "name": "DistRetainerInfo", "opcode": 23, "size": 210 - }, - { - "name": "CharacterCreated", - "opcode": 14, - "size": 2568 } ], "ClientLobbyIpcType": [ @@ -326,15 +326,15 @@ "opcode": 5, "size": 1144 }, - { - "name": "LobbyCharacterAction", - "opcode": 11, - "size": 496 - }, { "name": "ShandaLogin", "opcode": 6, "size": 1456 + }, + { + "name": "CharaMake", + "opcode": 11, + "size": 496 } ] } diff --git a/src/bin/kawari-lobby.rs b/src/bin/kawari-lobby.rs index c0a9295..9ecd38c 100644 --- a/src/bin/kawari-lobby.rs +++ b/src/bin/kawari-lobby.rs @@ -104,7 +104,7 @@ async fn main() { Some(connection.service_accounts[0].id); connection.send_lobby_info(*sequence).await } - ClientLobbyIpcData::LobbyCharacterAction(character_action) => { + ClientLobbyIpcData::CharaMake(character_action) => { connection.handle_character_action(character_action).await } ClientLobbyIpcData::ShandaLogin { unk } => { diff --git a/src/lobby/connection.rs b/src/lobby/connection.rs index b2ef774..0659076 100644 --- a/src/lobby/connection.rs +++ b/src/lobby/connection.rs @@ -83,19 +83,18 @@ impl LobbyConnection { /// Send the service account list to the client. pub async fn send_account_list(&mut self) { - let service_account_list = - ServerLobbyIpcData::LobbyServiceAccountList(LobbyServiceAccountList { - sequence: 0, - num_service_accounts: self.service_accounts.len() as u8, - unk1: 3, - unk2: 0x99, - service_accounts: self.service_accounts.to_vec(), - }); + let service_account_list = ServerLobbyIpcData::LoginReply(LobbyServiceAccountList { + sequence: 0, + num_service_accounts: self.service_accounts.len() as u8, + unk1: 3, + unk2: 0x99, + service_accounts: self.service_accounts.to_vec(), + }); let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyServiceAccountList, + op_code: ServerLobbyIpcType::LoginReply, server_id: 0, timestamp: timestamp_secs(), data: service_account_list, @@ -127,7 +126,7 @@ impl LobbyConnection { // add any empty boys servers.resize(6, Server::default()); - let lobby_server_list = ServerLobbyIpcData::LobbyServerList(LobbyServerList { + let lobby_server_list = ServerLobbyIpcData::DistWorldInfo(LobbyServerList { sequence: 0, unk1: 1, offset: 0, @@ -138,7 +137,7 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyServerList, + op_code: ServerLobbyIpcType::DistWorldInfo, server_id: 0, timestamp: timestamp_secs(), data: lobby_server_list, @@ -154,12 +153,12 @@ impl LobbyConnection { // send them the retainer list { - let lobby_retainer_list = ServerLobbyIpcData::LobbyRetainerList { unk1: 1 }; + let lobby_retainer_list = ServerLobbyIpcData::DistRetainerInfo { unk1: 1 }; let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyRetainerList, + op_code: ServerLobbyIpcType::DistRetainerInfo, server_id: 0, timestamp: timestamp_secs(), data: lobby_retainer_list, @@ -261,10 +260,10 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyCharacterList, + op_code: ServerLobbyIpcType::ServiceLoginReply, server_id: 0, timestamp: timestamp_secs(), - data: ServerLobbyIpcData::LobbyCharacterList(lobby_character_list), + data: ServerLobbyIpcData::ServiceLoginReply(lobby_character_list), }; self.send_segment(PacketSegment { @@ -281,7 +280,7 @@ impl LobbyConnection { pub async fn send_enter_world(&mut self, sequence: u64, content_id: u64, actor_id: u32) { let config = get_config(); - let enter_world = ServerLobbyIpcData::LobbyEnterWorld { + let enter_world = ServerLobbyIpcData::GameLoginReply { sequence, actor_id, content_id, @@ -293,7 +292,7 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyEnterWorld, + op_code: ServerLobbyIpcType::GameLoginReply, server_id: 0, timestamp: timestamp_secs(), data: enter_world, @@ -309,7 +308,7 @@ impl LobbyConnection { /// Send a lobby error to the client. pub async fn send_error(&mut self, sequence: u64, error: u32, exd_error: u16) { - let lobby_error = ServerLobbyIpcData::LobbyError { + let lobby_error = ServerLobbyIpcData::NackReply { sequence, error, value: 0, @@ -320,7 +319,7 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyError, + op_code: ServerLobbyIpcType::NackReply, server_id: 0, timestamp: timestamp_secs(), data: lobby_error, @@ -369,10 +368,10 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::CharacterCreated, + op_code: ServerLobbyIpcType::CharaMakeReply, server_id: 0, timestamp: 0, - data: ServerLobbyIpcData::CharacterCreated { + data: ServerLobbyIpcData::CharaMakeReply { sequence: character_action.sequence + 1, unk1: 0x1, unk2: 0x1, @@ -396,10 +395,10 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::LobbyError, + op_code: ServerLobbyIpcType::NackReply, server_id: 0, timestamp: 0, - data: ServerLobbyIpcData::LobbyError { + data: ServerLobbyIpcData::NackReply { sequence: character_action.sequence, error: 0x00000bdb, exd_error_id: 0x32cc, @@ -461,10 +460,10 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::CharacterCreated, + op_code: ServerLobbyIpcType::CharaMakeReply, server_id: 0, timestamp: 0, - data: ServerLobbyIpcData::CharacterCreated { + data: ServerLobbyIpcData::CharaMakeReply { sequence: character_action.sequence + 1, unk1: 0x1, unk2: 0x1, @@ -513,10 +512,10 @@ impl LobbyConnection { let ipc = ServerLobbyIpcSegment { unk1: 0, unk2: 0, - op_code: ServerLobbyIpcType::CharacterCreated, // FIXME: a TERRIBLE name for this packet + op_code: ServerLobbyIpcType::CharaMakeReply, server_id: 0, timestamp: 0, - data: ServerLobbyIpcData::CharacterCreated { + data: ServerLobbyIpcData::CharaMakeReply { sequence: character_action.sequence + 1, unk1: 0x1, unk2: 0x1, diff --git a/src/lobby/ipc/mod.rs b/src/lobby/ipc/mod.rs index dee0b72..3f89144 100644 --- a/src/lobby/ipc/mod.rs +++ b/src/lobby/ipc/mod.rs @@ -62,10 +62,10 @@ impl Default for ServerLobbyIpcSegment { Self { unk1: 0x14, unk2: 0, - op_code: ServerLobbyIpcType::LobbyError, + op_code: ServerLobbyIpcType::NackReply, server_id: 0, timestamp: 0, - data: ServerLobbyIpcData::LobbyError { + data: ServerLobbyIpcData::NackReply { sequence: 0, error: 0, value: 0, @@ -80,6 +80,20 @@ impl Default for ServerLobbyIpcSegment { #[br(import(magic: &ClientLobbyIpcType))] #[derive(Debug, Clone)] pub enum ClientLobbyIpcData { + /// Sent by the client when it requests the character list in the lobby. + #[br(pre_assert(*magic == ClientLobbyIpcType::ServiceLogin))] + ServiceLogin { + #[brw(pad_before = 16)] + sequence: u64, + // TODO: what is in here? + }, + /// Sent by the client when it requests to enter a world. + #[br(pre_assert(*magic == ClientLobbyIpcType::GameLogin))] + GameLogin { + sequence: u64, + content_id: u64, + // TODO: what else is in here? + }, /// Sent by the client after exchanging encryption information with the lobby server. #[br(pre_assert(*magic == ClientLobbyIpcType::LoginEx))] LoginEx { @@ -98,50 +112,47 @@ pub enum ClientLobbyIpcData { version_info: String, // unknown stuff at the end, it's not completely empty }, - /// Sent by the client when it requests the character list in the lobby. - #[br(pre_assert(*magic == ClientLobbyIpcType::ServiceLogin))] - ServiceLogin { - #[brw(pad_before = 16)] - sequence: u64, - // TODO: what is in here? - }, - /// Sent by the client when they request something about the character (e.g. deletion.) - #[br(pre_assert(*magic == ClientLobbyIpcType::LobbyCharacterAction))] - LobbyCharacterAction(LobbyCharacterAction), - /// Sent by the client when it requests to enter a world. - #[br(pre_assert(*magic == ClientLobbyIpcType::GameLogin))] - GameLogin { - sequence: u64, - content_id: u64, - // TODO: what else is in here? - }, #[br(pre_assert(*magic == ClientLobbyIpcType::ShandaLogin))] ShandaLogin { #[bw(pad_size_to = 1456)] #[br(count = 1456)] unk: Vec, }, + /// Sent by the client when they request something about the character (e.g. deletion.) + #[br(pre_assert(*magic == ClientLobbyIpcType::CharaMake))] + CharaMake(LobbyCharacterAction), } #[binrw] #[br(import(_magic: &ServerLobbyIpcType))] #[derive(Debug, Clone)] pub enum ServerLobbyIpcData { - /// Sent by the server to inform the client of their service accounts. - LobbyServiceAccountList(LobbyServiceAccountList), - /// Sent by the server to inform the client of their servers. - LobbyServerList(LobbyServerList), - /// Sent by the server to inform the client of their retainers. - LobbyRetainerList { - // TODO: what is in here? - #[brw(pad_before = 7)] - #[brw(pad_after = 202)] - unk1: u8, + /// Sent by the server to indicate an lobby error occured. + NackReply { + sequence: u64, + error: u32, + value: u32, + exd_error_id: u16, + #[brw(pad_after = 516)] // empty and garbage + unk1: u16, }, + /// Sent by the server to inform the client of their service accounts. + LoginReply(LobbyServiceAccountList), /// Sent by the server to inform the client of their characters. - LobbyCharacterList(LobbyCharacterList), + ServiceLoginReply(LobbyCharacterList), + // Assumed what this is, but probably incorrect + CharaMakeReply { + sequence: u64, + unk1: u8, + unk2: u8, + #[brw(pad_after = 1)] // empty + action: LobbyCharacterActionKind, + #[brw(pad_before = 36)] // empty + #[brw(pad_after = 1336)] // empty and garbage + details: CharacterDetails, + }, /// Sent by the server to tell the client how to connect to the world server. - LobbyEnterWorld { + GameLoginReply { sequence: u64, actor_id: u32, #[brw(pad_before = 4)] @@ -160,25 +171,14 @@ pub enum ServerLobbyIpcData { #[bw(map = write_string)] host: String, }, - /// Sent by the server to indicate an lobby error occured. - LobbyError { - sequence: u64, - error: u32, - value: u32, - exd_error_id: u16, - #[brw(pad_after = 516)] // empty and garbage - unk1: u16, - }, - // Assumed what this is, but probably incorrect - CharacterCreated { - sequence: u64, + /// Sent by the server to inform the client of their servers. + DistWorldInfo(LobbyServerList), + /// Sent by the server to inform the client of their retainers. + DistRetainerInfo { + // TODO: what is in here? + #[brw(pad_before = 7)] + #[brw(pad_after = 202)] unk1: u8, - unk2: u8, - #[brw(pad_after = 1)] // empty - action: LobbyCharacterActionKind, - #[brw(pad_before = 36)] // empty - #[brw(pad_after = 1336)] // empty and garbage - details: CharacterDetails, }, } @@ -195,24 +195,24 @@ mod tests { fn lobby_ipc_sizes() { let ipc_types = [ ( - ServerLobbyIpcType::LobbyServiceAccountList, - ServerLobbyIpcData::LobbyServiceAccountList(LobbyServiceAccountList::default()), + ServerLobbyIpcType::LoginReply, + ServerLobbyIpcData::LoginReply(LobbyServiceAccountList::default()), ), ( - ServerLobbyIpcType::LobbyServerList, - ServerLobbyIpcData::LobbyServerList(LobbyServerList::default()), + ServerLobbyIpcType::DistWorldInfo, + ServerLobbyIpcData::DistWorldInfo(LobbyServerList::default()), ), ( - ServerLobbyIpcType::LobbyRetainerList, - ServerLobbyIpcData::LobbyRetainerList { unk1: 0 }, + ServerLobbyIpcType::DistRetainerInfo, + ServerLobbyIpcData::DistRetainerInfo { unk1: 0 }, ), ( - ServerLobbyIpcType::LobbyCharacterList, - ServerLobbyIpcData::LobbyCharacterList(LobbyCharacterList::default()), + ServerLobbyIpcType::ServiceLoginReply, + ServerLobbyIpcData::ServiceLoginReply(LobbyCharacterList::default()), ), ( - ServerLobbyIpcType::LobbyEnterWorld, - ServerLobbyIpcData::LobbyEnterWorld { + ServerLobbyIpcType::GameLoginReply, + ServerLobbyIpcData::GameLoginReply { sequence: 0, actor_id: 0, content_id: 0, @@ -222,8 +222,8 @@ mod tests { }, ), ( - ServerLobbyIpcType::LobbyError, - ServerLobbyIpcData::LobbyError { + ServerLobbyIpcType::NackReply, + ServerLobbyIpcData::NackReply { sequence: 0, error: 0, value: 0, @@ -232,8 +232,8 @@ mod tests { }, ), ( - ServerLobbyIpcType::CharacterCreated, - ServerLobbyIpcData::CharacterCreated { + ServerLobbyIpcType::CharaMakeReply, + ServerLobbyIpcData::CharaMakeReply { sequence: 0, unk1: 0, unk2: 0,