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>;
|
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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue