1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-09 23:47:46 +00:00
kawari/src/packet/ipc.rs
Joshua Goins fb46a44e18 Begin correctly implementing packet obsfucation
I re-implemented Unscrambler, but in reverse! This currently only
affects names in the PlayerSpawn packet, it needs to be extended
into others to be considered complete.

See #9
2025-07-03 16:12:19 -04:00

67 lines
2.2 KiB
Rust

use binrw::{BinRead, BinWrite, binrw};
/// Required to implement for specializations of `IpcSegment`. These should be read/writeable, however for client packets you can leave calc_size() unimplemented.
pub trait ReadWriteIpcSegment:
for<'a> BinRead<Args<'a> = (&'a u32,)> + 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 seen in retail instead of guessing.
fn calc_size(&self) -> u32;
/// Returns a human-readable name of the opcode.
fn get_name(&self) -> &'static str;
/// Returns the integer opcode.
fn get_opcode(&self) -> u16;
}
/// An IPC packet segment.
/// When implementing a new connection type, `OpCode` and `Data` can be used to specialize this type:
/// ```
/// # use binrw::binrw;
/// # use kawari::packet::IpcSegment;
/// #
/// # #[binrw]
/// # #[brw(repr = u16)]
/// # #[derive(Clone, PartialEq, Debug)]
/// # pub enum ClientLobbyIpcType {
/// # Dummy = 0x1,
/// # }
/// #
/// # #[binrw]
/// # #[br(import(magic: &ClientLobbyIpcType))]
/// # #[derive(Debug, Clone)]
/// # pub enum ClientLobbyIpcData {
/// # Dummy()
/// # }
/// #
/// pub type ClientLobbyIpcSegment = IpcSegment<ClientLobbyIpcType, ClientLobbyIpcData>;
/// ```
#[binrw]
#[derive(Debug, Clone)]
#[br(import(size: &u32))]
pub struct IpcSegment<OpCode, Data>
where
for<'a> OpCode: BinRead<Args<'a> = ()> + 'a + std::fmt::Debug,
for<'a> OpCode: BinWrite<Args<'a> = ()> + 'a + std::fmt::Debug,
for<'a> Data: BinRead<Args<'a> = (&'a OpCode, &'a u32)> + 'a + std::fmt::Debug,
for<'a> Data: BinWrite<Args<'a> = ()> + 'a + std::fmt::Debug,
{
/// Unknown purpose, but usually 20.
pub unk1: u8,
/// Unknown purpose, but usually 0.
pub unk2: u8,
/// The opcode for this segment.
pub op_code: OpCode,
#[brw(pad_before = 2)] // empty
/// Unknown purpose, but safe to keep 0.
pub option: u16,
/// The timestamp of this packet in seconds since UNIX epoch.
pub timestamp: u32,
/// The data associated with the opcode.
#[brw(pad_before = 4)]
#[br(args(&op_code, size))]
pub data: Data,
}
pub const IPC_HEADER_SIZE: u32 = 16;