2025-03-08 14:09:57 -05:00
|
|
|
use std::{fs::write, io::Cursor};
|
2025-03-08 13:58:24 -05:00
|
|
|
|
2025-03-08 14:38:31 -05:00
|
|
|
use binrw::{BinRead, binrw, helpers::until_eof};
|
2025-03-08 14:09:57 -05:00
|
|
|
|
|
|
|
pub(crate) fn read_bool_from<T: std::convert::From<u8> + std::cmp::PartialEq>(x: T) -> bool {
|
|
|
|
x == T::from(1u8)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn write_bool_as<T: std::convert::From<u8>>(x: &bool) -> T {
|
|
|
|
if *x { T::from(1u8) } else { T::from(0u8) }
|
|
|
|
}
|
|
|
|
|
2025-03-08 14:38:31 -05:00
|
|
|
pub(crate) fn read_string(byte_stream: Vec<u8>) -> String {
|
|
|
|
let str = String::from_utf8(byte_stream).unwrap();
|
|
|
|
str.trim_matches(char::from(0)).to_string() // trim \0 from the end of strings
|
|
|
|
}
|
|
|
|
|
2025-03-08 14:09:57 -05:00
|
|
|
#[binrw]
|
|
|
|
#[brw(repr = u16)]
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum ConnectionType {
|
|
|
|
Lobby = 0x3,
|
|
|
|
}
|
|
|
|
|
2025-03-08 14:38:31 -05:00
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum SegmentType {
|
|
|
|
#[brw(magic = 0x9u32)]
|
|
|
|
InitializeEncryption {
|
|
|
|
#[br(pad_before = 36)] // empty
|
|
|
|
#[br(count = 64)]
|
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(ignore)]
|
|
|
|
phrase: String,
|
|
|
|
|
|
|
|
#[br(pad_after = 512)] // empty
|
|
|
|
key: u32,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2025-03-08 14:09:57 -05:00
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct PacketHeader {
|
|
|
|
unk1: u64,
|
|
|
|
unk2: u64,
|
|
|
|
timestamp: u64,
|
|
|
|
size: u32,
|
|
|
|
connection_type: ConnectionType,
|
2025-03-08 14:38:31 -05:00
|
|
|
segment_count: u16,
|
2025-03-08 14:09:57 -05:00
|
|
|
unk3: u8,
|
|
|
|
#[br(map = read_bool_from::<u8>)]
|
|
|
|
#[bw(map = write_bool_as::<u8>)]
|
|
|
|
compressed: bool,
|
2025-03-08 14:38:31 -05:00
|
|
|
unk4: u16,
|
|
|
|
unk5: u32, // iolite says the size after oodle decompression
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct PacketSegment {
|
|
|
|
size: u32,
|
|
|
|
source_actor: u32,
|
|
|
|
target_actor: u32,
|
|
|
|
segment_type: SegmentType,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct Packet {
|
|
|
|
header: PacketHeader,
|
|
|
|
#[br(count = header.segment_count)]
|
|
|
|
segments: Vec<PacketSegment>,
|
2025-03-08 14:09:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn dump(msg: &str, data: &[u8]) {
|
2025-03-08 13:58:24 -05:00
|
|
|
write("packet.bin", data);
|
2025-03-08 14:09:57 -05:00
|
|
|
panic!("{msg} Dumped to packet.bin.");
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn parse_packet(data: &[u8]) {
|
|
|
|
let mut cursor = Cursor::new(data);
|
|
|
|
|
2025-03-08 14:38:31 -05:00
|
|
|
if let Ok(packet) = Packet::read_le(&mut cursor) {
|
2025-03-08 14:09:57 -05:00
|
|
|
println!("{:#?}", packet);
|
|
|
|
|
2025-03-08 14:38:31 -05:00
|
|
|
if packet.header.size as usize != data.len() {
|
|
|
|
dump(
|
|
|
|
"Packet size mismatch between what we're given and the header!",
|
|
|
|
data,
|
|
|
|
);
|
2025-03-08 14:09:57 -05:00
|
|
|
}
|
2025-03-08 14:38:31 -05:00
|
|
|
|
|
|
|
dump("nothing", data);
|
2025-03-08 14:09:57 -05:00
|
|
|
} else {
|
|
|
|
dump("Failed to parse packet!", data);
|
|
|
|
}
|
2025-03-08 13:58:24 -05:00
|
|
|
}
|