mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-09 15:37:45 +00:00
Fill out more unknowns in lobby IPC packets
Mostly based off of Sapphire, but fixed in the more modern age.
This commit is contained in:
parent
24edee6548
commit
2f1aee9d09
6 changed files with 119 additions and 49 deletions
|
@ -280,7 +280,7 @@ async fn main() {
|
|||
connection.send_error(*sequence, 2002, 13006).await;
|
||||
}
|
||||
}
|
||||
ClientLobbyIpcData::ServiceLogin { sequence } => {
|
||||
ClientLobbyIpcData::ServiceLogin { sequence, .. } => {
|
||||
// TODO: support selecting a service account
|
||||
connection.selected_service_account =
|
||||
Some(connection.service_accounts[0].id);
|
||||
|
|
43
src/ipc/lobby/dist_retainer_info.rs
Normal file
43
src/ipc/lobby/dist_retainer_info.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::common::{CHAR_NAME_MAX_LENGTH, read_string, write_string};
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct RetainerInfo {
|
||||
id: u64,
|
||||
owner_id: u64,
|
||||
slot_id: u8,
|
||||
param1: u8,
|
||||
status: u16,
|
||||
param2: u32,
|
||||
#[bw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
|
||||
#[br(count = CHAR_NAME_MAX_LENGTH)]
|
||||
#[br(map = read_string)]
|
||||
#[bw(map = write_string)]
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl RetainerInfo {
|
||||
pub const SIZE: usize = 56;
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct DistRetainerInfo {
|
||||
pub sequence: u64,
|
||||
pub timestamp: u32,
|
||||
pub index: u8,
|
||||
pub count: u8,
|
||||
pub option_param: u16,
|
||||
pub option_arg: u32,
|
||||
pub num_contracted: u16,
|
||||
pub num_active: u16,
|
||||
pub num_total: u16,
|
||||
pub num_free_slots: u16,
|
||||
pub total_retainers: u16,
|
||||
pub active_retainers: u16,
|
||||
#[br(count = 9)]
|
||||
#[brw(pad_size_to = (9 * RetainerInfo::SIZE))]
|
||||
pub characters: Vec<RetainerInfo>,
|
||||
}
|
|
@ -12,6 +12,12 @@ pub use server_list::{DistWorldInfo, Server};
|
|||
mod login_reply;
|
||||
pub use login_reply::{LoginReply, ServiceAccount};
|
||||
|
||||
mod dist_retainer_info;
|
||||
pub use dist_retainer_info::{DistRetainerInfo, RetainerInfo};
|
||||
|
||||
mod nack_reply;
|
||||
pub use nack_reply::NackReply;
|
||||
|
||||
use crate::{
|
||||
common::{read_string, write_string},
|
||||
opcodes::{ClientLobbyIpcType, ServerLobbyIpcType},
|
||||
|
@ -48,6 +54,8 @@ impl Default for ClientLobbyIpcSegment {
|
|||
session_id: String::new(),
|
||||
version_info: String::new(),
|
||||
unk1: 0,
|
||||
timestamp: 0,
|
||||
unk2: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -78,13 +86,7 @@ impl Default for ServerLobbyIpcSegment {
|
|||
op_code: ServerLobbyIpcType::NackReply,
|
||||
option: 0,
|
||||
timestamp: 0,
|
||||
data: ServerLobbyIpcData::NackReply {
|
||||
sequence: 0,
|
||||
error: 0,
|
||||
value: 0,
|
||||
exd_error_id: 0,
|
||||
unk1: 0,
|
||||
},
|
||||
data: ServerLobbyIpcData::NackReply(NackReply::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,9 +98,12 @@ 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?
|
||||
account_index: u8,
|
||||
unk1: u8,
|
||||
unk2: u16,
|
||||
unk3: u32, // TODO: probably multiple params
|
||||
account_id: u64,
|
||||
},
|
||||
/// Sent by the client when it requests to enter a world.
|
||||
#[br(pre_assert(*magic == ClientLobbyIpcType::GameLogin))]
|
||||
|
@ -113,8 +118,9 @@ pub enum ClientLobbyIpcData {
|
|||
#[br(pre_assert(*magic == ClientLobbyIpcType::LoginEx))]
|
||||
LoginEx {
|
||||
sequence: u64,
|
||||
|
||||
#[brw(pad_before = 10)] // full of nonsense i don't understand yet
|
||||
timestamp: u32,
|
||||
#[brw(pad_after = 2)]
|
||||
unk1: u32,
|
||||
#[br(count = 64)]
|
||||
#[bw(pad_size_to = 64)]
|
||||
#[br(map = read_string)]
|
||||
|
@ -128,7 +134,7 @@ pub enum ClientLobbyIpcData {
|
|||
version_info: String,
|
||||
|
||||
#[brw(pad_before = 910)] // empty
|
||||
unk1: u64,
|
||||
unk2: u64,
|
||||
},
|
||||
#[br(pre_assert(*magic == ClientLobbyIpcType::ShandaLogin))]
|
||||
ShandaLogin {
|
||||
|
@ -151,14 +157,7 @@ pub enum ClientLobbyIpcData {
|
|||
pub enum ServerLobbyIpcData {
|
||||
/// Sent by the server to indicate an lobby error occured.
|
||||
#[br(pre_assert(*magic == ServerLobbyIpcType::NackReply))]
|
||||
NackReply {
|
||||
sequence: u64,
|
||||
error: u32,
|
||||
value: u32,
|
||||
exd_error_id: u16,
|
||||
#[brw(pad_after = 516)] // empty and garbage
|
||||
unk1: u16,
|
||||
},
|
||||
NackReply(NackReply),
|
||||
/// Sent by the server to inform the client of their service accounts.
|
||||
#[br(pre_assert(*magic == ServerLobbyIpcType::LoginReply))]
|
||||
LoginReply(LoginReply),
|
||||
|
@ -203,12 +202,7 @@ pub enum ServerLobbyIpcData {
|
|||
DistWorldInfo(DistWorldInfo),
|
||||
/// Sent by the server to inform the client of their retainers.
|
||||
#[br(pre_assert(*magic == ServerLobbyIpcType::DistRetainerInfo))]
|
||||
DistRetainerInfo {
|
||||
// TODO: what is in here?
|
||||
#[brw(pad_before = 7)]
|
||||
#[brw(pad_after = 528)]
|
||||
unk1: u8,
|
||||
},
|
||||
DistRetainerInfo(DistRetainerInfo),
|
||||
Unknown {
|
||||
#[br(count = size - 32)]
|
||||
unk: Vec<u8>,
|
||||
|
@ -229,13 +223,7 @@ mod tests {
|
|||
let ipc_types = [
|
||||
(
|
||||
ServerLobbyIpcType::NackReply,
|
||||
ServerLobbyIpcData::NackReply {
|
||||
sequence: 0,
|
||||
error: 0,
|
||||
value: 0,
|
||||
exd_error_id: 0,
|
||||
unk1: 0,
|
||||
},
|
||||
ServerLobbyIpcData::NackReply(NackReply::default()),
|
||||
),
|
||||
(
|
||||
ServerLobbyIpcType::LoginReply,
|
||||
|
@ -272,7 +260,7 @@ mod tests {
|
|||
),
|
||||
(
|
||||
ServerLobbyIpcType::DistRetainerInfo,
|
||||
ServerLobbyIpcData::DistRetainerInfo { unk1: 0 },
|
||||
ServerLobbyIpcData::DistRetainerInfo(DistRetainerInfo::default()),
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -306,7 +294,14 @@ mod tests {
|
|||
let ipc_types = [
|
||||
(
|
||||
ClientLobbyIpcType::ServiceLogin,
|
||||
ClientLobbyIpcData::ServiceLogin { sequence: 0 },
|
||||
ClientLobbyIpcData::ServiceLogin {
|
||||
sequence: 0,
|
||||
account_index: 0,
|
||||
unk1: 0,
|
||||
unk2: 0,
|
||||
account_id: 0,
|
||||
unk3: 0,
|
||||
},
|
||||
),
|
||||
(
|
||||
ClientLobbyIpcType::GameLogin,
|
||||
|
@ -324,6 +319,8 @@ mod tests {
|
|||
session_id: String::default(),
|
||||
version_info: String::default(),
|
||||
unk1: 0,
|
||||
timestamp: 0,
|
||||
unk2: 0,
|
||||
},
|
||||
),
|
||||
(
|
||||
|
|
27
src/ipc/lobby/nack_reply.rs
Normal file
27
src/ipc/lobby/nack_reply.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
#![allow(unused_variables)] // whoop binrw
|
||||
|
||||
use binrw::binrw;
|
||||
|
||||
use crate::common::{read_string, write_string};
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct NackReply {
|
||||
pub sequence: u64,
|
||||
/// The error code shown in the client.
|
||||
pub error: u32,
|
||||
/// Value is specific to each error, e.g. your position in queue (i think)
|
||||
pub value: u32,
|
||||
/// The ID of a row in the Error Excel sheet.
|
||||
pub exd_error_id: u16,
|
||||
#[br(temp)]
|
||||
#[bw(calc = message.len() as u16)]
|
||||
pub message_size: u16,
|
||||
/// Seems to be unused
|
||||
#[brw(pad_after = 4)] // garbage
|
||||
#[bw(pad_size_to = 512)]
|
||||
#[br(count = 512)]
|
||||
#[br(map = read_string)]
|
||||
#[bw(map = write_string)]
|
||||
pub message: String,
|
||||
}
|
|
@ -68,6 +68,10 @@ pub struct CharacterDetails {
|
|||
pub unk3: [u32; 5],
|
||||
}
|
||||
|
||||
impl CharacterDetails {
|
||||
pub const SIZE: usize = 1196;
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ServiceLoginReply {
|
||||
|
@ -93,6 +97,6 @@ pub struct ServiceLoginReply {
|
|||
#[brw(pad_after = 12)]
|
||||
pub entitled_expansion: u32,
|
||||
#[br(count = 2)]
|
||||
#[brw(pad_size_to = (1196 * 2))]
|
||||
#[brw(pad_size_to = (CharacterDetails::SIZE * 2))]
|
||||
pub characters: Vec<CharacterDetails>,
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ use crate::{
|
|||
blowfish::Blowfish,
|
||||
common::timestamp_secs,
|
||||
config::get_config,
|
||||
ipc::lobby::{DistRetainerInfo, NackReply},
|
||||
opcodes::ServerLobbyIpcType,
|
||||
packet::oodle::OodleNetwork,
|
||||
packet::{
|
||||
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentData, SegmentType,
|
||||
generate_encryption_key, parse_packet, send_packet,
|
||||
generate_encryption_key, oodle::OodleNetwork, parse_packet, send_packet,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -120,7 +120,7 @@ impl LobbyConnection {
|
|||
servers.resize(6, Server::default());
|
||||
|
||||
let lobby_server_list = ServerLobbyIpcData::DistWorldInfo(DistWorldInfo {
|
||||
sequence: 0,
|
||||
sequence,
|
||||
unk1: 1,
|
||||
num_servers: 1,
|
||||
servers,
|
||||
|
@ -144,7 +144,8 @@ impl LobbyConnection {
|
|||
|
||||
// send them the retainer list
|
||||
{
|
||||
let lobby_retainer_list = ServerLobbyIpcData::DistRetainerInfo { unk1: 1 };
|
||||
let lobby_retainer_list =
|
||||
ServerLobbyIpcData::DistRetainerInfo(DistRetainerInfo::default());
|
||||
|
||||
let ipc = ServerLobbyIpcSegment {
|
||||
op_code: ServerLobbyIpcType::DistRetainerInfo,
|
||||
|
@ -272,13 +273,12 @@ 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::NackReply {
|
||||
let lobby_error = ServerLobbyIpcData::NackReply(NackReply {
|
||||
sequence,
|
||||
error,
|
||||
value: 0,
|
||||
exd_error_id: exd_error,
|
||||
unk1: 1,
|
||||
};
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let ipc = ServerLobbyIpcSegment {
|
||||
op_code: ServerLobbyIpcType::NackReply,
|
||||
|
@ -350,13 +350,12 @@ impl LobbyConnection {
|
|||
} else {
|
||||
let ipc = ServerLobbyIpcSegment {
|
||||
op_code: ServerLobbyIpcType::NackReply,
|
||||
data: ServerLobbyIpcData::NackReply {
|
||||
data: ServerLobbyIpcData::NackReply(NackReply {
|
||||
sequence: character_action.sequence,
|
||||
error: 0x00000bdb,
|
||||
exd_error_id: 0x32cc,
|
||||
value: 0,
|
||||
unk1: 0,
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue