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:
parent
ed5cdef528
commit
0e7e1f8078
7 changed files with 66 additions and 19 deletions
Binary file not shown.
Binary file not shown.
|
@ -21,7 +21,17 @@ use crate::{
|
|||
|
||||
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
|
||||
impl Default for ClientLobbyIpcSegment {
|
||||
|
|
|
@ -47,11 +47,22 @@ pub(crate) fn decompress<T: ReadWriteIpcSegment>(
|
|||
let mut cursor = Cursor::new(&data);
|
||||
|
||||
for _ in 0..header.segment_count {
|
||||
let current_position = cursor.position();
|
||||
segments.push(PacketSegment::read_options(
|
||||
&mut cursor,
|
||||
endian,
|
||||
(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)
|
||||
|
|
|
@ -6,9 +6,7 @@ pub trait ReadWriteIpcSegment:
|
|||
{
|
||||
/// 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.
|
||||
fn calc_size(&self) -> u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
fn calc_size(&self) -> u32;
|
||||
}
|
||||
|
||||
/// An IPC packet segment.
|
||||
|
@ -47,6 +45,7 @@ where
|
|||
/// Unknown purpose, but usually 0.
|
||||
pub unk2: u8,
|
||||
/// The opcode for this segment.
|
||||
#[br(dbg)]
|
||||
pub op_code: OpCode,
|
||||
#[brw(pad_before = 2)] // empty
|
||||
/// Unknown purpose, but safe to keep 0.
|
||||
|
|
|
@ -15,7 +15,7 @@ use super::{
|
|||
|
||||
#[binrw]
|
||||
#[brw(repr = u16)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ConnectionType {
|
||||
None = 0x0,
|
||||
Zone = 0x1,
|
||||
|
@ -108,7 +108,7 @@ pub struct PacketSegment<T: ReadWriteIpcSegment> {
|
|||
}
|
||||
|
||||
impl<T: ReadWriteIpcSegment> PacketSegment<T> {
|
||||
fn calc_size(&self) -> u32 {
|
||||
pub fn calc_size(&self) -> u32 {
|
||||
let header = std::mem::size_of::<u32>() * 4;
|
||||
header as u32
|
||||
+ match &self.segment_type {
|
||||
|
@ -118,7 +118,7 @@ impl<T: ReadWriteIpcSegment> PacketSegment<T> {
|
|||
SegmentType::KeepAlive { .. } => 0x8,
|
||||
SegmentType::KeepAliveResponse { .. } => 0x8,
|
||||
SegmentType::ZoneInitialize { .. } => 40,
|
||||
SegmentType::InitializeSession { .. } => todo!(),
|
||||
SegmentType::InitializeSession { .. } => 40,
|
||||
SegmentType::CustomIpc { data } => data.calc_size(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,34 @@ use crate::packet::ReadWriteIpcSegment;
|
|||
|
||||
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
|
||||
impl Default for ClientZoneIpcSegment {
|
||||
|
@ -72,7 +99,7 @@ impl Default for ClientZoneIpcSegment {
|
|||
op_code: ClientZoneIpcType::InitRequest,
|
||||
server_id: 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
|
||||
PlayerSpawn = 0x331,
|
||||
/// Sent by the server as response to ZoneInitRequest.
|
||||
InitResponse = 0x2D0,
|
||||
InitResponse = 0x223,
|
||||
// Sent by the server to indicate the log out is complete
|
||||
LogOutComplete = 0x69,
|
||||
// Sent by the server to modify the client's position
|
||||
|
@ -212,20 +239,20 @@ pub enum ServerZoneIpcType {
|
|||
#[derive(Clone, PartialEq, Debug)]
|
||||
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)
|
||||
InitRequest = 0x2ED,
|
||||
InitRequest = 0x2AB,
|
||||
// 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
|
||||
Unk1 = 0x37C,
|
||||
Unk1 = 0x364,
|
||||
// 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
|
||||
Unk3 = 0x326,
|
||||
Unk3 = 0x2AF,
|
||||
// FIXME: 8 bytes of something from the client, not sure what yet
|
||||
Unk4 = 0x143,
|
||||
Unk4 = 0x178,
|
||||
SetSearchInfoHandler = 0x20A,
|
||||
// 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
|
||||
SocialListRequest = 0x1A1,
|
||||
// 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))]
|
||||
InitRequest {
|
||||
// TODO: full of possibly interesting information
|
||||
unk: [u8; 105],
|
||||
unk: [u8; 120],
|
||||
},
|
||||
#[br(pre_assert(*magic == ClientZoneIpcType::FinishLoading))]
|
||||
FinishLoading {
|
||||
|
@ -347,7 +374,7 @@ pub enum ClientZoneIpcData {
|
|||
#[br(pre_assert(*magic == ClientZoneIpcType::Unk2))]
|
||||
Unk2 {
|
||||
// TODO: full of possibly interesting information
|
||||
unk: [u8; 8],
|
||||
unk: [u8; 16],
|
||||
},
|
||||
#[br(pre_assert(*magic == ClientZoneIpcType::Unk3))]
|
||||
Unk3 {
|
||||
|
|
Loading…
Add table
Reference in a new issue