mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-25 08:27:44 +00:00
Move some larger Lobby IPC structs to their own files, add more tests for these
Also fix a bunch of mistakes when calculating size, and so on.
This commit is contained in:
parent
f5d75301b2
commit
7315ece194
7 changed files with 129 additions and 111 deletions
|
@ -120,8 +120,8 @@ async fn main() {
|
||||||
server_id: 0,
|
server_id: 0,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
data: ServerLobbyIpcData::CharacterCreated {
|
data: ServerLobbyIpcData::CharacterCreated {
|
||||||
unk1: 0x4,
|
sequence: 0x4, // TODO: haha no
|
||||||
unk2: 0x00010101,
|
unk: 0x00010101,
|
||||||
details: CharacterDetails {
|
details: CharacterDetails {
|
||||||
content_id: CONTENT_ID,
|
content_id: CONTENT_ID,
|
||||||
character_name: name.clone(),
|
character_name: name.clone(),
|
||||||
|
@ -160,8 +160,8 @@ async fn main() {
|
||||||
server_id: 0,
|
server_id: 0,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
data: ServerLobbyIpcData::CharacterCreated {
|
data: ServerLobbyIpcData::CharacterCreated {
|
||||||
unk1: 0x5,
|
sequence: 0x5,
|
||||||
unk2: 0x00020101,
|
unk: 0x00020101,
|
||||||
details: CharacterDetails {
|
details: CharacterDetails {
|
||||||
id: 0x07369f3a, // notice that we give them an id now
|
id: 0x07369f3a, // notice that we give them an id now
|
||||||
content_id: CONTENT_ID,
|
content_id: CONTENT_ID,
|
||||||
|
|
|
@ -16,8 +16,8 @@ use crate::{
|
||||||
use super::{
|
use super::{
|
||||||
client_select_data::ClientSelectData,
|
client_select_data::ClientSelectData,
|
||||||
ipc::{
|
ipc::{
|
||||||
CharacterDetails, Server, ServerLobbyIpcData, ServerLobbyIpcSegment, ServerLobbyIpcType,
|
CharacterDetails, LobbyCharacterList, LobbyServerList, LobbyServiceAccountList, Server,
|
||||||
ServiceAccount,
|
ServerLobbyIpcData, ServerLobbyIpcSegment, ServerLobbyIpcType, ServiceAccount,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::lobby::ipc::ClientLobbyIpcSegment;
|
use crate::lobby::ipc::ClientLobbyIpcSegment;
|
||||||
|
@ -74,13 +74,14 @@ impl LobbyConnection {
|
||||||
}]
|
}]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
let service_account_list = ServerLobbyIpcData::LobbyServiceAccountList {
|
let service_account_list =
|
||||||
sequence: 0,
|
ServerLobbyIpcData::LobbyServiceAccountList(LobbyServiceAccountList {
|
||||||
num_service_accounts: service_accounts.len() as u8,
|
sequence: 0,
|
||||||
unk1: 3,
|
num_service_accounts: service_accounts.len() as u8,
|
||||||
unk2: 0x99,
|
unk1: 3,
|
||||||
service_accounts: service_accounts.to_vec(),
|
unk2: 0x99,
|
||||||
};
|
service_accounts: service_accounts.to_vec(),
|
||||||
|
});
|
||||||
|
|
||||||
let ipc = ServerLobbyIpcSegment {
|
let ipc = ServerLobbyIpcSegment {
|
||||||
unk1: 0,
|
unk1: 0,
|
||||||
|
@ -114,13 +115,13 @@ impl LobbyConnection {
|
||||||
// add any empty boys
|
// add any empty boys
|
||||||
servers.resize(6, Server::default());
|
servers.resize(6, Server::default());
|
||||||
|
|
||||||
let lobby_server_list = ServerLobbyIpcData::LobbyServerList {
|
let lobby_server_list = ServerLobbyIpcData::LobbyServerList(LobbyServerList {
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
unk1: 1,
|
unk1: 1,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
num_servers: 1,
|
num_servers: 1,
|
||||||
servers,
|
servers,
|
||||||
};
|
});
|
||||||
|
|
||||||
let ipc = ServerLobbyIpcSegment {
|
let ipc = ServerLobbyIpcSegment {
|
||||||
unk1: 0,
|
unk1: 0,
|
||||||
|
@ -223,7 +224,7 @@ impl LobbyConnection {
|
||||||
|
|
||||||
let lobby_character_list = if i == 3 {
|
let lobby_character_list = if i == 3 {
|
||||||
// On the last packet, add the account-wide information
|
// On the last packet, add the account-wide information
|
||||||
ServerLobbyIpcData::LobbyCharacterList {
|
LobbyCharacterList {
|
||||||
sequence,
|
sequence,
|
||||||
counter: (i * 4) + 1, // TODO: why the + 1 here?
|
counter: (i * 4) + 1, // TODO: why the + 1 here?
|
||||||
num_in_packet: characters_in_packet.len() as u8,
|
num_in_packet: characters_in_packet.len() as u8,
|
||||||
|
@ -244,7 +245,7 @@ impl LobbyConnection {
|
||||||
characters: characters_in_packet,
|
characters: characters_in_packet,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ServerLobbyIpcData::LobbyCharacterList {
|
LobbyCharacterList {
|
||||||
sequence,
|
sequence,
|
||||||
counter: i * 4,
|
counter: i * 4,
|
||||||
num_in_packet: characters_in_packet.len() as u8,
|
num_in_packet: characters_in_packet.len() as u8,
|
||||||
|
@ -272,7 +273,7 @@ impl LobbyConnection {
|
||||||
op_code: ServerLobbyIpcType::LobbyCharacterList,
|
op_code: ServerLobbyIpcType::LobbyCharacterList,
|
||||||
server_id: 0,
|
server_id: 0,
|
||||||
timestamp: timestamp_secs(),
|
timestamp: timestamp_secs(),
|
||||||
data: lobby_character_list,
|
data: ServerLobbyIpcData::LobbyCharacterList(lobby_character_list),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.send_segment(PacketSegment {
|
self.send_segment(PacketSegment {
|
||||||
|
|
|
@ -37,3 +37,32 @@ pub struct CharacterDetails {
|
||||||
pub character_detail_json: String,
|
pub character_detail_json: String,
|
||||||
pub unk2: [u8; 20],
|
pub unk2: [u8; 20],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct LobbyCharacterList {
|
||||||
|
pub sequence: u64,
|
||||||
|
pub counter: u8,
|
||||||
|
#[brw(pad_after = 2)]
|
||||||
|
pub num_in_packet: u8,
|
||||||
|
pub unk1: u8,
|
||||||
|
pub unk2: u8,
|
||||||
|
pub unk3: u8,
|
||||||
|
/// Set to 128 if legacy character
|
||||||
|
pub unk4: u8,
|
||||||
|
pub unk5: [u32; 7],
|
||||||
|
pub unk6: u8,
|
||||||
|
pub veteran_rank: u8,
|
||||||
|
#[brw(pad_after = 1)]
|
||||||
|
pub unk7: u8,
|
||||||
|
pub days_subscribed: u32,
|
||||||
|
pub remaining_days: u32,
|
||||||
|
pub days_to_next_rank: u32,
|
||||||
|
pub max_characters_on_world: u16,
|
||||||
|
pub unk8: u16,
|
||||||
|
#[brw(pad_after = 12)]
|
||||||
|
pub entitled_expansion: u32,
|
||||||
|
#[br(count = 2)]
|
||||||
|
#[brw(pad_size_to = (1196 * 2))]
|
||||||
|
pub characters: Vec<CharacterDetails>,
|
||||||
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ mod character_action;
|
||||||
pub use character_action::LobbyCharacterAction;
|
pub use character_action::LobbyCharacterAction;
|
||||||
|
|
||||||
mod character_list;
|
mod character_list;
|
||||||
pub use character_list::CharacterDetails;
|
pub use character_list::{CharacterDetails, LobbyCharacterList};
|
||||||
|
|
||||||
mod client_version_info;
|
mod client_version_info;
|
||||||
|
|
||||||
mod server_list;
|
mod server_list;
|
||||||
pub use server_list::Server;
|
pub use server_list::{LobbyServerList, Server};
|
||||||
|
|
||||||
mod service_account_list;
|
mod service_account_list;
|
||||||
pub use service_account_list::ServiceAccount;
|
pub use service_account_list::{LobbyServiceAccountList, ServiceAccount};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CHAR_NAME_MAX_LENGTH,
|
CHAR_NAME_MAX_LENGTH,
|
||||||
|
@ -53,10 +53,10 @@ impl IpcSegmentTrait for ServerLobbyIpcSegment {
|
||||||
// 16 is the size of the IPC header
|
// 16 is the size of the IPC header
|
||||||
16 + match self.op_code {
|
16 + match self.op_code {
|
||||||
ServerLobbyIpcType::LobbyError => 536,
|
ServerLobbyIpcType::LobbyError => 536,
|
||||||
ServerLobbyIpcType::LobbyServiceAccountList => 24 + (8 * 80),
|
ServerLobbyIpcType::LobbyServiceAccountList => 656,
|
||||||
ServerLobbyIpcType::LobbyCharacterList => 80 + (2 * 1184),
|
ServerLobbyIpcType::LobbyCharacterList => 2472,
|
||||||
ServerLobbyIpcType::LobbyEnterWorld => 160,
|
ServerLobbyIpcType::LobbyEnterWorld => 160,
|
||||||
ServerLobbyIpcType::LobbyServerList => 24 + (6 * 84),
|
ServerLobbyIpcType::LobbyServerList => 528,
|
||||||
ServerLobbyIpcType::LobbyRetainerList => 210,
|
ServerLobbyIpcType::LobbyRetainerList => 210,
|
||||||
ServerLobbyIpcType::CharacterCreated => 2568,
|
ServerLobbyIpcType::CharacterCreated => 2568,
|
||||||
}
|
}
|
||||||
|
@ -178,59 +178,15 @@ pub enum ClientLobbyIpcData {
|
||||||
#[br(import(_magic: &ServerLobbyIpcType))]
|
#[br(import(_magic: &ServerLobbyIpcType))]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ServerLobbyIpcData {
|
pub enum ServerLobbyIpcData {
|
||||||
LobbyServiceAccountList {
|
LobbyServiceAccountList(LobbyServiceAccountList),
|
||||||
#[br(dbg)]
|
LobbyServerList(LobbyServerList),
|
||||||
sequence: u64,
|
|
||||||
#[brw(pad_before = 1)]
|
|
||||||
num_service_accounts: u8,
|
|
||||||
unk1: u8,
|
|
||||||
#[brw(pad_after = 4)]
|
|
||||||
unk2: u8,
|
|
||||||
#[br(count = 8)]
|
|
||||||
service_accounts: Vec<ServiceAccount>,
|
|
||||||
},
|
|
||||||
LobbyServerList {
|
|
||||||
sequence: u64,
|
|
||||||
unk1: u16,
|
|
||||||
offset: u16,
|
|
||||||
#[brw(pad_after = 8)]
|
|
||||||
num_servers: u32,
|
|
||||||
#[br(count = 6)]
|
|
||||||
#[brw(pad_size_to = 504)]
|
|
||||||
servers: Vec<Server>,
|
|
||||||
},
|
|
||||||
LobbyRetainerList {
|
LobbyRetainerList {
|
||||||
// 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 = 202)]
|
||||||
unk1: u8,
|
unk1: u8,
|
||||||
},
|
},
|
||||||
LobbyCharacterList {
|
LobbyCharacterList(LobbyCharacterList),
|
||||||
sequence: u64,
|
|
||||||
counter: u8,
|
|
||||||
#[brw(pad_after = 2)]
|
|
||||||
num_in_packet: u8,
|
|
||||||
unk1: u8,
|
|
||||||
unk2: u8,
|
|
||||||
unk3: u8,
|
|
||||||
/// Set to 128 if legacy character
|
|
||||||
unk4: u8,
|
|
||||||
unk5: [u32; 7],
|
|
||||||
unk6: u8,
|
|
||||||
veteran_rank: u8,
|
|
||||||
#[brw(pad_after = 1)]
|
|
||||||
unk7: u8,
|
|
||||||
days_subscribed: u32,
|
|
||||||
remaining_days: u32,
|
|
||||||
days_to_next_rank: u32,
|
|
||||||
max_characters_on_world: u16,
|
|
||||||
unk8: u16,
|
|
||||||
#[brw(pad_after = 12)]
|
|
||||||
entitled_expansion: u32,
|
|
||||||
#[br(count = 2)]
|
|
||||||
#[brw(pad_size_to = 2368)]
|
|
||||||
characters: Vec<CharacterDetails>,
|
|
||||||
},
|
|
||||||
LobbyEnterWorld {
|
LobbyEnterWorld {
|
||||||
sequence: u64,
|
sequence: u64,
|
||||||
character_id: u32,
|
character_id: u32,
|
||||||
|
@ -243,8 +199,9 @@ pub enum ServerLobbyIpcData {
|
||||||
#[bw(map = write_string)]
|
#[bw(map = write_string)]
|
||||||
session_id: String,
|
session_id: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
#[brw(pad_after = 16)]
|
#[brw(pad_after = 16)] // garbage?
|
||||||
#[br(count = 48)]
|
#[br(count = 48)]
|
||||||
|
#[brw(pad_size_to = 48)]
|
||||||
#[br(map = read_string)]
|
#[br(map = read_string)]
|
||||||
#[bw(map = write_string)]
|
#[bw(map = write_string)]
|
||||||
host: String,
|
host: String,
|
||||||
|
@ -254,24 +211,14 @@ pub enum ServerLobbyIpcData {
|
||||||
error: u32,
|
error: u32,
|
||||||
value: u32,
|
value: u32,
|
||||||
exd_error_id: u16,
|
exd_error_id: u16,
|
||||||
|
#[brw(pad_after = 516)] // empty and garbage
|
||||||
unk1: u16,
|
unk1: u16,
|
||||||
},
|
},
|
||||||
NameRejection {
|
|
||||||
// FIXME: This is opcode 0x2, which is InitializeChat. We need to separate the lobby/zone IPC codes.
|
|
||||||
unk1: u8,
|
|
||||||
#[brw(pad_before = 7)] // empty
|
|
||||||
unk2: u16,
|
|
||||||
#[brw(pad_before = 6)] // empty
|
|
||||||
#[brw(pad_after = 516)] // mostly empty
|
|
||||||
unk3: u32,
|
|
||||||
},
|
|
||||||
CharacterCreated {
|
CharacterCreated {
|
||||||
#[brw(pad_after = 4)] // empty
|
sequence: u64,
|
||||||
unk1: u32,
|
unk: u32,
|
||||||
#[brw(pad_after = 4)] // empty
|
#[brw(pad_before = 36)] // empty
|
||||||
unk2: u32,
|
#[brw(pad_after = 1336)] // empty and garbage
|
||||||
#[brw(pad_before = 32)] // empty
|
|
||||||
#[brw(pad_after = 1136)] // empty
|
|
||||||
details: CharacterDetails,
|
details: CharacterDetails,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -288,37 +235,49 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn lobby_ipc_sizes() {
|
fn lobby_ipc_sizes() {
|
||||||
let ipc_types = [
|
let ipc_types = [
|
||||||
|
(
|
||||||
|
ServerLobbyIpcType::LobbyServiceAccountList,
|
||||||
|
ServerLobbyIpcData::LobbyServiceAccountList(LobbyServiceAccountList::default()),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::LobbyServerList,
|
ServerLobbyIpcType::LobbyServerList,
|
||||||
ServerLobbyIpcData::LobbyServerList {
|
ServerLobbyIpcData::LobbyServerList(LobbyServerList::default()),
|
||||||
sequence: 0,
|
),
|
||||||
unk1: 0,
|
(
|
||||||
offset: 0,
|
ServerLobbyIpcType::LobbyRetainerList,
|
||||||
num_servers: 0,
|
ServerLobbyIpcData::LobbyRetainerList { unk1: 0 },
|
||||||
servers: Vec::new(),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ServerLobbyIpcType::LobbyCharacterList,
|
ServerLobbyIpcType::LobbyCharacterList,
|
||||||
ServerLobbyIpcData::LobbyCharacterList {
|
ServerLobbyIpcData::LobbyCharacterList(LobbyCharacterList::default()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ServerLobbyIpcType::LobbyEnterWorld,
|
||||||
|
ServerLobbyIpcData::LobbyEnterWorld {
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
counter: 0,
|
character_id: 0,
|
||||||
num_in_packet: 0,
|
content_id: 0,
|
||||||
|
session_id: String::new(),
|
||||||
|
port: 0,
|
||||||
|
host: String::new(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ServerLobbyIpcType::LobbyError,
|
||||||
|
ServerLobbyIpcData::LobbyError {
|
||||||
|
sequence: 0,
|
||||||
|
error: 0,
|
||||||
|
value: 0,
|
||||||
|
exd_error_id: 0,
|
||||||
unk1: 0,
|
unk1: 0,
|
||||||
unk2: 0,
|
},
|
||||||
unk3: 0,
|
),
|
||||||
unk4: 0,
|
(
|
||||||
unk5: [0; 7],
|
ServerLobbyIpcType::CharacterCreated,
|
||||||
unk6: 0,
|
ServerLobbyIpcData::CharacterCreated {
|
||||||
veteran_rank: 0,
|
sequence: 0,
|
||||||
unk7: 0,
|
unk: 0,
|
||||||
days_subscribed: 0,
|
details: CharacterDetails::default(),
|
||||||
remaining_days: 0,
|
|
||||||
days_to_next_rank: 0,
|
|
||||||
max_characters_on_world: 0,
|
|
||||||
unk8: 0,
|
|
||||||
entitled_expansion: 0,
|
|
||||||
characters: Vec::new(),
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
|
@ -17,3 +17,16 @@ pub struct Server {
|
||||||
#[bw(map = write_string)]
|
#[bw(map = write_string)]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct LobbyServerList {
|
||||||
|
pub sequence: u64,
|
||||||
|
pub unk1: u16,
|
||||||
|
pub offset: u16,
|
||||||
|
#[brw(pad_after = 8)]
|
||||||
|
pub num_servers: u32,
|
||||||
|
#[br(count = 6)]
|
||||||
|
#[brw(pad_size_to = 504)]
|
||||||
|
pub servers: Vec<Server>,
|
||||||
|
}
|
||||||
|
|
|
@ -14,3 +14,17 @@ pub struct ServiceAccount {
|
||||||
#[bw(map = write_string)]
|
#[bw(map = write_string)]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct LobbyServiceAccountList {
|
||||||
|
pub sequence: u64,
|
||||||
|
#[brw(pad_before = 1)]
|
||||||
|
pub num_service_accounts: u8,
|
||||||
|
pub unk1: u8,
|
||||||
|
#[brw(pad_after = 4)]
|
||||||
|
pub unk2: u8,
|
||||||
|
#[br(count = 8)]
|
||||||
|
#[brw(pad_size_to = (8 * 80))]
|
||||||
|
pub service_accounts: Vec<ServiceAccount>,
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ use binrw::{BinRead, BinWrite, binrw};
|
||||||
pub trait IpcSegmentTrait:
|
pub trait IpcSegmentTrait:
|
||||||
for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()> + std::fmt::Debug + 'static
|
for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()> + std::fmt::Debug + 'static
|
||||||
{
|
{
|
||||||
|
/// Calculate the size of this Ipc segment *including* the 16 byte header.
|
||||||
|
/// When implementing this, please use the size as seen in retail.
|
||||||
fn calc_size(&self) -> u32;
|
fn calc_size(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue