mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-10 07:57:46 +00:00
Fix various size issues with lobby IPC packets
Some of these were the wrong size, and were affecting both the server and packet analyzer alike. This should now more accurately reflect retail.
This commit is contained in:
parent
7801398590
commit
24edee6548
4 changed files with 105 additions and 33 deletions
|
@ -412,7 +412,7 @@
|
||||||
{
|
{
|
||||||
"name": "DistRetainerInfo",
|
"name": "DistRetainerInfo",
|
||||||
"opcode": 23,
|
"opcode": 23,
|
||||||
"size": 210
|
"size": 536
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ClientLobbyIpcType": [
|
"ClientLobbyIpcType": [
|
||||||
|
|
|
@ -216,6 +216,7 @@ async fn main() {
|
||||||
sequence,
|
sequence,
|
||||||
session_id,
|
session_id,
|
||||||
version_info,
|
version_info,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"Client {session_id} ({version_info}) logging in!"
|
"Client {session_id} ({version_info}) logging in!"
|
||||||
|
@ -294,6 +295,7 @@ async fn main() {
|
||||||
ClientLobbyIpcData::GameLogin {
|
ClientLobbyIpcData::GameLogin {
|
||||||
sequence,
|
sequence,
|
||||||
content_id,
|
content_id,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
tracing::info!("Client is joining the world with {content_id}");
|
tracing::info!("Client is joining the world with {content_id}");
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,9 @@ use crate::common::CHAR_NAME_MAX_LENGTH;
|
||||||
use super::{read_string, write_string};
|
use super::{read_string, write_string};
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug, Default)]
|
||||||
pub enum LobbyCharacterActionKind {
|
pub enum LobbyCharacterActionKind {
|
||||||
|
#[default]
|
||||||
#[brw(magic = 0x1u8)]
|
#[brw(magic = 0x1u8)]
|
||||||
ReserveName,
|
ReserveName,
|
||||||
#[brw(magic = 0x2u8)]
|
#[brw(magic = 0x2u8)]
|
||||||
|
@ -34,11 +35,11 @@ pub enum LobbyCharacterActionKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug, Default)]
|
||||||
pub struct CharaMake {
|
pub struct CharaMake {
|
||||||
pub sequence: u64,
|
pub sequence: u64,
|
||||||
pub content_id: u64,
|
pub content_id: u64,
|
||||||
#[br(pad_before = 8)]
|
#[brw(pad_before = 8)]
|
||||||
pub character_index: u8,
|
pub character_index: u8,
|
||||||
pub action: LobbyCharacterActionKind,
|
pub action: LobbyCharacterActionKind,
|
||||||
pub world_id: u16,
|
pub world_id: u16,
|
||||||
|
|
|
@ -47,6 +47,7 @@ impl Default for ClientLobbyIpcSegment {
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
session_id: String::new(),
|
session_id: String::new(),
|
||||||
version_info: String::new(),
|
version_info: String::new(),
|
||||||
|
unk1: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +106,8 @@ pub enum ClientLobbyIpcData {
|
||||||
sequence: u64,
|
sequence: u64,
|
||||||
content_id: u64,
|
content_id: u64,
|
||||||
// TODO: what else is in here?
|
// TODO: what else is in here?
|
||||||
|
unk1: u64,
|
||||||
|
unk2: u64,
|
||||||
},
|
},
|
||||||
/// Sent by the client after exchanging encryption information with the lobby server.
|
/// Sent by the client after exchanging encryption information with the lobby server.
|
||||||
#[br(pre_assert(*magic == ClientLobbyIpcType::LoginEx))]
|
#[br(pre_assert(*magic == ClientLobbyIpcType::LoginEx))]
|
||||||
|
@ -113,15 +116,19 @@ pub enum ClientLobbyIpcData {
|
||||||
|
|
||||||
#[brw(pad_before = 10)] // full of nonsense i don't understand yet
|
#[brw(pad_before = 10)] // full of nonsense i don't understand yet
|
||||||
#[br(count = 64)]
|
#[br(count = 64)]
|
||||||
|
#[bw(pad_size_to = 64)]
|
||||||
#[br(map = read_string)]
|
#[br(map = read_string)]
|
||||||
#[bw(ignore)]
|
#[bw(map = write_string)]
|
||||||
session_id: String,
|
session_id: String,
|
||||||
|
|
||||||
#[br(count = 144)]
|
#[br(count = 144)]
|
||||||
|
#[bw(pad_size_to = 144)]
|
||||||
#[br(map = read_string)]
|
#[br(map = read_string)]
|
||||||
#[bw(ignore)]
|
#[bw(map = write_string)]
|
||||||
version_info: String,
|
version_info: String,
|
||||||
// unknown stuff at the end, it's not completely empty
|
|
||||||
|
#[brw(pad_before = 910)] // empty
|
||||||
|
unk1: u64,
|
||||||
},
|
},
|
||||||
#[br(pre_assert(*magic == ClientLobbyIpcType::ShandaLogin))]
|
#[br(pre_assert(*magic == ClientLobbyIpcType::ShandaLogin))]
|
||||||
ShandaLogin {
|
ShandaLogin {
|
||||||
|
@ -199,7 +206,7 @@ pub enum ServerLobbyIpcData {
|
||||||
DistRetainerInfo {
|
DistRetainerInfo {
|
||||||
// TODO: what is in here?
|
// TODO: what is in here?
|
||||||
#[brw(pad_before = 7)]
|
#[brw(pad_before = 7)]
|
||||||
#[brw(pad_after = 202)]
|
#[brw(pad_after = 528)]
|
||||||
unk1: u8,
|
unk1: u8,
|
||||||
},
|
},
|
||||||
Unknown {
|
Unknown {
|
||||||
|
@ -218,24 +225,36 @@ mod tests {
|
||||||
|
|
||||||
/// Ensure that the IPC data size as reported matches up with what we write
|
/// Ensure that the IPC data size as reported matches up with what we write
|
||||||
#[test]
|
#[test]
|
||||||
fn lobby_ipc_sizes() {
|
fn server_lobby_ipc_sizes() {
|
||||||
let ipc_types = [
|
let ipc_types = [
|
||||||
|
(
|
||||||
|
ServerLobbyIpcType::NackReply,
|
||||||
|
ServerLobbyIpcData::NackReply {
|
||||||
|
sequence: 0,
|
||||||
|
error: 0,
|
||||||
|
value: 0,
|
||||||
|
exd_error_id: 0,
|
||||||
|
unk1: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::LoginReply,
|
ServerLobbyIpcType::LoginReply,
|
||||||
ServerLobbyIpcData::LoginReply(LoginReply::default()),
|
ServerLobbyIpcData::LoginReply(LoginReply::default()),
|
||||||
),
|
),
|
||||||
(
|
|
||||||
ServerLobbyIpcType::DistWorldInfo,
|
|
||||||
ServerLobbyIpcData::DistWorldInfo(DistWorldInfo::default()),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
ServerLobbyIpcType::DistRetainerInfo,
|
|
||||||
ServerLobbyIpcData::DistRetainerInfo { unk1: 0 },
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::ServiceLoginReply,
|
ServerLobbyIpcType::ServiceLoginReply,
|
||||||
ServerLobbyIpcData::ServiceLoginReply(ServiceLoginReply::default()),
|
ServerLobbyIpcData::ServiceLoginReply(ServiceLoginReply::default()),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
ServerLobbyIpcType::CharaMakeReply,
|
||||||
|
ServerLobbyIpcData::CharaMakeReply {
|
||||||
|
sequence: 0,
|
||||||
|
unk1: 0,
|
||||||
|
unk2: 0,
|
||||||
|
action: LobbyCharacterActionKind::ReserveName,
|
||||||
|
details: CharacterDetails::default(),
|
||||||
|
},
|
||||||
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::GameLoginReply,
|
ServerLobbyIpcType::GameLoginReply,
|
||||||
ServerLobbyIpcData::GameLoginReply {
|
ServerLobbyIpcData::GameLoginReply {
|
||||||
|
@ -248,24 +267,12 @@ mod tests {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::NackReply,
|
ServerLobbyIpcType::DistWorldInfo,
|
||||||
ServerLobbyIpcData::NackReply {
|
ServerLobbyIpcData::DistWorldInfo(DistWorldInfo::default()),
|
||||||
sequence: 0,
|
|
||||||
error: 0,
|
|
||||||
value: 0,
|
|
||||||
exd_error_id: 0,
|
|
||||||
unk1: 0,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::CharaMakeReply,
|
ServerLobbyIpcType::DistRetainerInfo,
|
||||||
ServerLobbyIpcData::CharaMakeReply {
|
ServerLobbyIpcData::DistRetainerInfo { unk1: 0 },
|
||||||
sequence: 0,
|
|
||||||
unk1: 0,
|
|
||||||
unk2: 0,
|
|
||||||
action: LobbyCharacterActionKind::ReserveName,
|
|
||||||
details: CharacterDetails::default(),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -292,4 +299,66 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that the IPC data size as reported matches up with what we write
|
||||||
|
#[test]
|
||||||
|
fn client_lobby_ipc_sizes() {
|
||||||
|
let ipc_types = [
|
||||||
|
(
|
||||||
|
ClientLobbyIpcType::ServiceLogin,
|
||||||
|
ClientLobbyIpcData::ServiceLogin { sequence: 0 },
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ClientLobbyIpcType::GameLogin,
|
||||||
|
ClientLobbyIpcData::GameLogin {
|
||||||
|
sequence: 0,
|
||||||
|
content_id: 0,
|
||||||
|
unk1: 0,
|
||||||
|
unk2: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ClientLobbyIpcType::LoginEx,
|
||||||
|
ClientLobbyIpcData::LoginEx {
|
||||||
|
sequence: 0,
|
||||||
|
session_id: String::default(),
|
||||||
|
version_info: String::default(),
|
||||||
|
unk1: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ClientLobbyIpcType::ShandaLogin,
|
||||||
|
ClientLobbyIpcData::ShandaLogin {
|
||||||
|
unk: Vec::default(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ClientLobbyIpcType::CharaMake,
|
||||||
|
ClientLobbyIpcData::CharaMake(CharaMake::default()),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (opcode, ipc) in &ipc_types {
|
||||||
|
let mut cursor = Cursor::new(Vec::new());
|
||||||
|
|
||||||
|
let ipc_segment = ClientLobbyIpcSegment {
|
||||||
|
unk1: 0,
|
||||||
|
unk2: 0,
|
||||||
|
op_code: opcode.clone(),
|
||||||
|
option: 0,
|
||||||
|
timestamp: 0,
|
||||||
|
data: ipc.clone(),
|
||||||
|
};
|
||||||
|
ipc_segment.write_le(&mut cursor).unwrap();
|
||||||
|
|
||||||
|
let buffer = cursor.into_inner();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
buffer.len(),
|
||||||
|
ipc_segment.calc_size() as usize,
|
||||||
|
"{:#?} did not match size!",
|
||||||
|
opcode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue