1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-05-19 17:27:45 +00:00

More various 7.2 packet fixes, attempt to check recieved packet size

This commit is contained in:
Joshua Goins 2025-03-25 18:15:41 -04:00
parent ed5cdef528
commit 0e7e1f8078
7 changed files with 66 additions and 19 deletions

Binary file not shown.

Binary file not shown.

View file

@ -21,7 +21,17 @@ use crate::{
pub type ClientLobbyIpcSegment = IpcSegment<ClientLobbyIpcType, ClientLobbyIpcData>; pub type ClientLobbyIpcSegment = IpcSegment<ClientLobbyIpcType, ClientLobbyIpcData>;
impl ReadWriteIpcSegment for ClientLobbyIpcSegment {} impl ReadWriteIpcSegment for ClientLobbyIpcSegment {
fn calc_size(&self) -> u32 {
// 16 is the size of the IPC header
16 + match self.op_code {
ClientLobbyIpcType::RequestCharacterList => 24,
ClientLobbyIpcType::RequestEnterWorld => 32,
ClientLobbyIpcType::ClientVersionInfo => 1144,
ClientLobbyIpcType::LobbyCharacterAction => 496,
}
}
}
// TODO: make generic // TODO: make generic
impl Default for ClientLobbyIpcSegment { impl Default for ClientLobbyIpcSegment {

View file

@ -47,11 +47,22 @@ pub(crate) fn decompress<T: ReadWriteIpcSegment>(
let mut cursor = Cursor::new(&data); let mut cursor = Cursor::new(&data);
for _ in 0..header.segment_count { for _ in 0..header.segment_count {
let current_position = cursor.position();
segments.push(PacketSegment::read_options( segments.push(PacketSegment::read_options(
&mut cursor, &mut cursor,
endian, endian,
(encryption_key,), (encryption_key,),
)?); )?);
let new_position = cursor.position();
let expected_size = segments.last().unwrap().calc_size() as u64;
let actual_size = new_position - current_position;
if expected_size != actual_size {
tracing::warn!(
"The segment {:#?} does not match the size in calc_size()! (expected {expected_size} got {actual_size}",
segments.last()
);
}
} }
Ok(segments) Ok(segments)

View file

@ -6,9 +6,7 @@ pub trait ReadWriteIpcSegment:
{ {
/// Calculate the size of this Ipc segment *including* the 16 byte header. /// Calculate the size of this Ipc segment *including* the 16 byte header.
/// When implementing this, please use the size seen in retail instead of guessing. /// When implementing this, please use the size seen in retail instead of guessing.
fn calc_size(&self) -> u32 { fn calc_size(&self) -> u32;
unimplemented!()
}
} }
/// An IPC packet segment. /// An IPC packet segment.
@ -47,6 +45,7 @@ where
/// Unknown purpose, but usually 0. /// Unknown purpose, but usually 0.
pub unk2: u8, pub unk2: u8,
/// The opcode for this segment. /// The opcode for this segment.
#[br(dbg)]
pub op_code: OpCode, pub op_code: OpCode,
#[brw(pad_before = 2)] // empty #[brw(pad_before = 2)] // empty
/// Unknown purpose, but safe to keep 0. /// Unknown purpose, but safe to keep 0.

View file

@ -15,7 +15,7 @@ use super::{
#[binrw] #[binrw]
#[brw(repr = u16)] #[brw(repr = u16)]
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub enum ConnectionType { pub enum ConnectionType {
None = 0x0, None = 0x0,
Zone = 0x1, Zone = 0x1,
@ -108,7 +108,7 @@ pub struct PacketSegment<T: ReadWriteIpcSegment> {
} }
impl<T: ReadWriteIpcSegment> PacketSegment<T> { impl<T: ReadWriteIpcSegment> PacketSegment<T> {
fn calc_size(&self) -> u32 { pub fn calc_size(&self) -> u32 {
let header = std::mem::size_of::<u32>() * 4; let header = std::mem::size_of::<u32>() * 4;
header as u32 header as u32
+ match &self.segment_type { + match &self.segment_type {
@ -118,7 +118,7 @@ impl<T: ReadWriteIpcSegment> PacketSegment<T> {
SegmentType::KeepAlive { .. } => 0x8, SegmentType::KeepAlive { .. } => 0x8,
SegmentType::KeepAliveResponse { .. } => 0x8, SegmentType::KeepAliveResponse { .. } => 0x8,
SegmentType::ZoneInitialize { .. } => 40, SegmentType::ZoneInitialize { .. } => 40,
SegmentType::InitializeSession { .. } => todo!(), SegmentType::InitializeSession { .. } => 40,
SegmentType::CustomIpc { data } => data.calc_size(), SegmentType::CustomIpc { data } => data.calc_size(),
} }
} }

View file

@ -61,7 +61,34 @@ use crate::packet::ReadWriteIpcSegment;
pub type ClientZoneIpcSegment = IpcSegment<ClientZoneIpcType, ClientZoneIpcData>; pub type ClientZoneIpcSegment = IpcSegment<ClientZoneIpcType, ClientZoneIpcData>;
impl ReadWriteIpcSegment for ClientZoneIpcSegment {} impl ReadWriteIpcSegment for ClientZoneIpcSegment {
fn calc_size(&self) -> u32 {
// 16 is the size of the IPC header
16 + match self.op_code {
ClientZoneIpcType::InitRequest => 120,
ClientZoneIpcType::FinishLoading => 72,
ClientZoneIpcType::Unk1 => 32,
ClientZoneIpcType::Unk2 => 16,
ClientZoneIpcType::Unk3 => 8,
ClientZoneIpcType::Unk4 => 8,
ClientZoneIpcType::SetSearchInfoHandler => 8,
ClientZoneIpcType::Unk5 => 8,
ClientZoneIpcType::SocialListRequest => 16,
ClientZoneIpcType::Unk7 => 32,
ClientZoneIpcType::UpdatePositionHandler => 24,
ClientZoneIpcType::LogOut => 8,
ClientZoneIpcType::Disconnected => 8,
ClientZoneIpcType::ChatMessage => todo!(),
ClientZoneIpcType::GameMasterCommand => todo!(),
ClientZoneIpcType::Unk12 => todo!(),
ClientZoneIpcType::EnterZoneLine => todo!(),
ClientZoneIpcType::Unk13 => todo!(),
ClientZoneIpcType::Unk14 => todo!(),
ClientZoneIpcType::ActionRequest => todo!(),
ClientZoneIpcType::Unk15 => todo!(),
}
}
}
// TODO: make generic // TODO: make generic
impl Default for ClientZoneIpcSegment { impl Default for ClientZoneIpcSegment {
@ -72,7 +99,7 @@ impl Default for ClientZoneIpcSegment {
op_code: ClientZoneIpcType::InitRequest, op_code: ClientZoneIpcType::InitRequest,
server_id: 0, server_id: 0,
timestamp: 0, timestamp: 0,
data: ClientZoneIpcData::InitRequest { unk: [0; 105] }, data: ClientZoneIpcData::InitRequest { unk: [0; 120] },
} }
} }
} }
@ -166,7 +193,7 @@ pub enum ServerZoneIpcType {
// Sent by the server to spawn the player in // Sent by the server to spawn the player in
PlayerSpawn = 0x331, PlayerSpawn = 0x331,
/// Sent by the server as response to ZoneInitRequest. /// Sent by the server as response to ZoneInitRequest.
InitResponse = 0x2D0, InitResponse = 0x223,
// Sent by the server to indicate the log out is complete // Sent by the server to indicate the log out is complete
LogOutComplete = 0x69, LogOutComplete = 0x69,
// Sent by the server to modify the client's position // Sent by the server to modify the client's position
@ -212,20 +239,20 @@ pub enum ServerZoneIpcType {
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum ClientZoneIpcType { pub enum ClientZoneIpcType {
/// Sent by the client when they successfully initialize with the server, and they need several bits of information (e.g. what zone to load) /// Sent by the client when they successfully initialize with the server, and they need several bits of information (e.g. what zone to load)
InitRequest = 0x2ED, InitRequest = 0x2AB,
// Sent by the client when they're done loading and they need to be spawned in // Sent by the client when they're done loading and they need to be spawned in
FinishLoading = 0x397, // TODO: assumed FinishLoading = 0x1AB,
// FIXME: 32 bytes of something from the client, not sure what yet // FIXME: 32 bytes of something from the client, not sure what yet
Unk1 = 0x37C, Unk1 = 0x364,
// FIXME: 16 bytes of something from the client, not sure what yet // FIXME: 16 bytes of something from the client, not sure what yet
Unk2 = 0x2E5, Unk2 = 0x1D8,
// FIXME: 8 bytes of something from the client, not sure what yet // FIXME: 8 bytes of something from the client, not sure what yet
Unk3 = 0x326, Unk3 = 0x2AF,
// FIXME: 8 bytes of something from the client, not sure what yet // FIXME: 8 bytes of something from the client, not sure what yet
Unk4 = 0x143, Unk4 = 0x178,
SetSearchInfoHandler = 0x20A, SetSearchInfoHandler = 0x20A,
// FIXME: 8 bytes of something from the client, not sure what yet // FIXME: 8 bytes of something from the client, not sure what yet
Unk5 = 0x2D0, Unk5 = 0x223,
// Sent by the client when it requests the friends list and other related info // Sent by the client when it requests the friends list and other related info
SocialListRequest = 0x1A1, SocialListRequest = 0x1A1,
// FIXME: 32 bytes of something from the client, not sure what yet // FIXME: 32 bytes of something from the client, not sure what yet
@ -332,7 +359,7 @@ pub enum ClientZoneIpcData {
#[br(pre_assert(*magic == ClientZoneIpcType::InitRequest))] #[br(pre_assert(*magic == ClientZoneIpcType::InitRequest))]
InitRequest { InitRequest {
// TODO: full of possibly interesting information // TODO: full of possibly interesting information
unk: [u8; 105], unk: [u8; 120],
}, },
#[br(pre_assert(*magic == ClientZoneIpcType::FinishLoading))] #[br(pre_assert(*magic == ClientZoneIpcType::FinishLoading))]
FinishLoading { FinishLoading {
@ -347,7 +374,7 @@ pub enum ClientZoneIpcData {
#[br(pre_assert(*magic == ClientZoneIpcType::Unk2))] #[br(pre_assert(*magic == ClientZoneIpcType::Unk2))]
Unk2 { Unk2 {
// TODO: full of possibly interesting information // TODO: full of possibly interesting information
unk: [u8; 8], unk: [u8; 16],
}, },
#[br(pre_assert(*magic == ClientZoneIpcType::Unk3))] #[br(pre_assert(*magic == ClientZoneIpcType::Unk3))]
Unk3 { Unk3 {