diff --git a/src/lib.rs b/src/lib.rs index 272503c..c917aa4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ pub mod crypto; pub mod packet; pub mod character; +use std::io::Read; #[derive(Debug, PartialEq)] pub enum PacketParseError { NotEnoughBytes, @@ -10,6 +11,66 @@ pub enum PacketParseError { WrongPacketSize(u16, usize), DataStructNotLargeEnough(u64, usize), InvalidValue, + ReadError, +} + + +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]; + cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + Ok(bytes[0]) + } + fn as_bytes(&self) -> Vec { + vec![*self] + } +} + +impl PSOPacketData for u32 { + fn from_bytes(cursor: &mut R) -> Result { + let mut bytes = [0u8; 4]; + cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + Ok(u32::from_le_bytes(bytes)) + } + fn as_bytes(&self) -> Vec { + u32::to_le_bytes(*self).to_vec() + } +} + +impl PSOPacketData for u16 { + fn from_bytes(cursor: &mut R) -> Result { + let mut bytes = [0u8; 2]; + cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + Ok(u16::from_le_bytes(bytes)) + } + fn as_bytes(&self) -> Vec { + u16::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 + } }