#![allow(incomplete_features)] pub mod crypto; pub mod packet; pub mod character; pub mod util; pub mod item; use std::io::{Read, Seek}; #[derive(Debug, PartialEq)] pub enum PacketParseError { NotEnoughBytes, WrongPacketCommand {expected: u16, got: u16}, WrongPacketForServerType(u16, Vec), UnknownPacket(u16, Vec), WrongPacketSize(u16, usize), WrongMessageCommand {expected: u8, got: u8}, UnknownMessage(u8, Vec), DataStructNotLargeEnough(u64, usize), InvalidValue, ReadError, } pub trait PSOPacketData { //fn size(&self) -> usize; fn from_bytes(cursor: &mut R) -> Result where Self: Sized; fn as_bytes(&self) -> Vec; } impl PSOPacketData for u8 { fn from_bytes(cursor: &mut R) -> Result { let mut bytes = [0u8; 1]; let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; if len == 1 { Ok(bytes[0]) } else{ Err(PacketParseError::NotEnoughBytes) } } fn as_bytes(&self) -> Vec { vec![*self] } } impl PSOPacketData for u16 { fn from_bytes(cursor: &mut R) -> Result { let mut bytes = [0u8; 2]; let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; if len == 2 { Ok(u16::from_le_bytes(bytes)) } else { Err(PacketParseError::NotEnoughBytes) } } fn as_bytes(&self) -> Vec { u16::to_le_bytes(*self).to_vec() } } impl PSOPacketData for u32 { fn from_bytes(cursor: &mut R) -> Result { let mut bytes = [0u8; 4]; let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; if len == 4 { Ok(u32::from_le_bytes(bytes)) } else { Err(PacketParseError::NotEnoughBytes) } } fn as_bytes(&self) -> Vec { u32::to_le_bytes(*self).to_vec() } } impl PSOPacketData for f32 { fn from_bytes(cursor: &mut R) -> Result { let mut bytes = [0u8; 4]; let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; if len == 4 { Ok(f32::from_le_bytes(bytes)) } else { Err(PacketParseError::NotEnoughBytes) } } fn as_bytes(&self) -> Vec { f32::to_le_bytes(*self).to_vec() } } impl PSOPacketData for String { fn from_bytes(cursor: &mut R) -> Result { let mut s: Vec = Vec::new(); cursor.read_to_end(&mut s).map_err(|_| PacketParseError::ReadError)?; let mut utf16 = Vec::new(); for c in s.chunks(2) { utf16.push(u16::from_le_bytes([c[0], c[1]])); } Ok(String::from_utf16_lossy(utf16.as_slice())) } fn as_bytes(&self) -> Vec { let mut buf = Vec::new(); for c in self.as_str().encode_utf16() { buf.extend_from_slice(&c.to_le_bytes()); } buf } } #[derive(Debug, Clone, PartialEq)] pub struct ConsumingBlob { pub blob: Vec, } impl PSOPacketData for ConsumingBlob { fn from_bytes(cursor: &mut R) -> Result { let mut blob: Vec = Vec::new(); cursor.read_to_end(&mut blob).map_err(|_| PacketParseError::ReadError)?; Ok(ConsumingBlob { blob: blob, }) } fn as_bytes(&self) -> Vec { self.blob.clone() } } pub trait PSOPacket: std::fmt::Debug { // const CMD: u16; fn from_bytes(data: &[u8]) -> Result where Self: Sized; fn as_bytes(&self) -> Vec; } #[cfg(test)] mod test { use super::*; use psopacket::{pso_packet, pso_message, PSOPacketData}; use crate::packet::messages::PSOMessage; #[test] fn test_basic_pso_packet() { #[pso_packet(0x23)] struct Test { a: u32, b: u16, c: u16, } let test = Test { a: 123456789, b: 54321, c: 9999, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![16, 0, 35, 0, 0, 0, 0, 0, 21, 205, 91, 7, 49, 212, 15, 39]); bytes[11] = 17; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 291228949, b: 54321, c: 9999, }); } #[test] fn test_array_in_packet() { #[pso_packet(0x23)] struct Test { a: u32, b: u16, c: [u16; 3], } let test = Test { a: 123456789, b: 54321, c: [1111, 2222, 3333], }; let mut bytes = test.as_bytes(); assert!(bytes == [20, 0, 35, 0, 0, 0, 0, 0, 21, 205, 91, 7, 49, 212, 87, 4, 174, 8, 5, 13]); bytes[17] = 17; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 123456789, b: 54321, c: [1111, 4526, 3333], }); } #[test] fn test_custom_type_in_packet() { #[derive(Clone, Debug, PartialEq)] pub struct MyType { k: u8, j: u32, } impl PSOPacketData for MyType { fn from_bytes(cursor: &mut R) -> Result { let mut kb = [0u8; 1]; cursor.read(&mut kb).map_err(|_| PacketParseError::ReadError)?; let mut jb = [0u8; 4]; cursor.read(&mut jb).map_err(|_| PacketParseError::ReadError)?; Ok(MyType { k: kb[0], j: u32::from_le_bytes(jb) }) } fn as_bytes(&self) -> Vec { let jbytes = u32::to_le_bytes(self.j); vec![self.k, jbytes[0], jbytes[1], jbytes[2], jbytes[3]] } } #[pso_packet(0x23)] struct Test { a: u32, b: u16, c: MyType, d: u8, } let test = Test { a: 123456789, b: 54321, c: MyType { k: 23, j: 999999, }, d: 5, }; let mut bytes = test.as_bytes(); assert!(bytes == [20, 0, 35, 0, 0, 0, 0, 0, 21, 205, 91, 7, 49, 212, 23, 63, 66, 15, 0, 5]); bytes[17] = 17; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 123456789, b: 54321, c: MyType { k: 23, j: 1131071, }, d: 5, }); } #[test] fn test_string_in_packet() { #[pso_packet(0x23)] struct Test { a: u32, b: u16, s: String, } let test = Test { a: 123456789, b: 54321, s: "asdf あえいおう".to_string(), }; let mut bytes = test.as_bytes(); assert!(bytes == vec![36, 0, 35, 0, 0, 0, 0, 0, 21, 205, 91, 7, 49, 212, 97, 0, 115, 0, 100, 0, 102, 0, 32, 0, 66, 48, 72, 48, 68, 48, 74, 48, 70, 48, 0, 0]); bytes[18] = 99; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 123456789, b: 54321, s: "ascf あえいおう\u{0}".to_string(), }); } #[test] fn test_vec_in_packet() { #[pso_packet(0x23)] struct Test { a: u32, b: u16, v: Vec, } let test = Test { a: 123456789, b: 54321, v: vec![123,456,789], }; let mut bytes = test.as_bytes(); assert!(bytes == vec![20, 0, 35, 0, 3, 0, 0, 0, 21, 205, 91, 7, 49, 212, 123, 0, 200, 1, 21, 3]); bytes[18] = 99; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 123456789, b: 54321, v: vec![123,456,867], }); } #[test] fn test_no_flag_packet() { #[pso_packet(0x23, no_flag)] struct Test { a: u32, b: u16, c: u16, } let test = Test { a: 123456789, b: 54321, c: 9999, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![12, 0, 35, 0, 21, 205, 91, 7, 49, 212, 15, 39]); bytes[11] = 17; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { a: 123456789, b: 54321, c: 4367, }); } #[test] fn test_command_error() { #[pso_packet(0x23)] struct Test { a: u32, b: u16, #[nodebug] c: [u8; 0x2000], } let test = Test { a: 123456789, b: 54321, c: [0; 0x2000], }; let mut bytes = test.as_bytes(); bytes[2] = 17; let test2 = Test::from_bytes(&bytes); assert!(test2 == Err(PacketParseError::WrongPacketCommand { expected: 0x23, got: 17})); } #[test] fn test_derive_pso_data_packet() { #[derive(PSOPacketData)] struct Test { a: u8, b: u32, c: u16, } let test = Test { a: 12, b: 34567, c: 890, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![12, 7, 135, 0, 0, 122, 3]); bytes[2] = 17; let mut cur = std::io::Cursor::new(bytes.clone()); let test2 = Test::from_bytes(&mut cur).unwrap(); assert!(test2 == Test { a: 12, b: 4359, c: 890 }); } #[test] fn test_derive_pso_data_packet_array() { #[derive(PSOPacketData)] struct Test { a: u8, b: u32, c: u16, d: [u8; 5], } let test = Test { a: 12, b: 34567, c: 890, d: [1,2,3,4,5], }; let mut bytes = test.as_bytes(); assert!(bytes == vec![12, 7, 135, 0, 0, 122, 3, 1, 2, 3, 4, 5]); bytes[10] = 17; let mut cur = std::io::Cursor::new(bytes.clone()); let test2 = Test::from_bytes(&mut cur).unwrap(); assert!(test2 == Test { a: 12, b: 34567, c: 890, d: [1,2,3,17,5] }); } #[test] fn test_derive_pso_data_packet_not_enough_data() { #[derive(PSOPacketData)] struct Test { a: u8, b: u32, c: u16, } let test = Test { a: 12, b: 34567, c: 890, }; let mut bytes = test.as_bytes(); bytes.extend(test.as_bytes()); let mut cur = std::io::Cursor::new(bytes.clone()); let test2 = Test::from_bytes(&mut cur).unwrap(); assert!(test2 == Test { a: 12, b: 34567, c: 890, }); let bytes2 = (0..14).collect::>(); let mut cur = std::io::Cursor::new(bytes2); let test3 = Test::from_bytes(&mut cur); assert!(test3 == Ok(Test { a: 0, b: 67305985, c: 1541, })); let test4 = Test::from_bytes(&mut cur); assert!(test4 == Ok(Test { a: 7, b: 185207048, c: 3340, })); let test5 = Test::from_bytes(&mut cur); assert!(test5 == Err(PacketParseError::NotEnoughBytes)); } #[test] fn test_pso_packet_manual_flag() { #[pso_packet(0x23, manual_flag)] struct Test { flag: u32, a: u32, b: u32, } let test = Test { flag: 99, a: 123, b: 456, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![16, 0, 35, 0, 99, 0, 0, 0, 123, 0, 0, 0, 200, 1, 0, 0]); bytes[6] = 2; let test2 = Test::from_bytes(&bytes).unwrap(); assert!(test2 == Test { flag: 131171, a: 123, b: 456, }); } #[test] fn test_pso_message() { #[pso_message(0x23)] struct Test { a: u32, b: f32, } let test = Test { client: 1, target: 2, a: 123, b: 4.56, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![35, 3, 1, 2, 123, 0, 0, 0, 133, 235, 145, 64]); bytes[6] = 2; let test2 = Test::from_bytes(&mut std::io::Cursor::new(bytes)).unwrap(); assert!(test2 == Test { client: 1, target: 2, a: 131195, b: 4.56, }); } #[test] fn test_pso_message_non_4_byte_size() { #[pso_message(0x23)] struct Test { a: u32, b: f32, c: u8, } let test = Test { client: 1, target: 2, a: 123, b: 4.56, c: 5, }; let mut bytes = test.as_bytes(); assert!(bytes == vec![35, 4, 1, 2, 123, 0, 0, 0, 133, 235, 145, 64, 5, 0, 0, 0]); bytes[6] = 2; let test2 = Test::from_bytes(&mut std::io::Cursor::new(bytes)).unwrap(); assert!(test2 == Test { client: 1, target: 2, a: 131195, b: 4.56, c: 5, }); } #[test] fn test_pso_message_overflow() { #[pso_message(0x23)] struct Test { b: [u32; 100], } let test = Test { client: 1, target: 2, b: [23; 100], }; let bytes = test.as_bytes(); assert!(bytes[1] == 101); } #[test] fn test_consuming_blob() { #[pso_packet(0x6D, manual_flag)] struct SixDee { flag: u32, blob: ConsumingBlob, } let pkt = vec![76, 0, 109, 0, 1, 0, 0, 0, 109, 0, 0, 0, 68, 0, 0, 0, 140, 0, 0, 0, 51, 0, 0, 0, 84, 220, 255, 254, 253, 1, 254, 240, 33, 254, 240, 65, 254, 240, 85, 97, 254, 240, 129, 254, 240, 161, 254, 240, 193, 254, 240, 169, 225, 13, 1, 16, 0, 33, 16, 0, 65, 16, 0, 97, 0, 16, 1, 64, 15, 82, 15, 100, 15, 118, 0, 0]; let data = SixDee::from_bytes(&pkt); assert!(pkt == data.unwrap().as_bytes()); } #[test] fn test_message_length() { #[pso_message(0x23)] struct Lengths { a: u8, #[length_of(d)] b: u8, c: u8, #[length_is(b)] d: Vec, } let pkt = Lengths { client: 1, target: 2, a: 12, b: 23, c: 34, d: vec![9,9,9], }; let mut data = pkt.as_bytes(); assert!(data == vec![35, 3, 1, 2, 12, 3, 34, 9, 9, 9, 0, 0]); data[10] = 8; data[5] = 4; let l = Lengths::from_bytes(&mut std::io::Cursor::new(data)).unwrap(); assert!(l == Lengths { client: 1, target: 2, a: 12, b: 4, c: 34, d: vec![9,9,9,8], }); } }