Advertisement
Guest User

D2 Protocol codec

a guest
Oct 23rd, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.25 KB | None | 0 0
  1. use std::io::{Read, Write};
  2.  
  3. const LH_SZ_LEN_ALL: u16 = 0b0000_0011;
  4. const LH_SZ_LEN_8: u16   = 0b0000_0001;
  5. const LH_SZ_LEN_16: u16  = 0b0000_0010;
  6. const LH_SZ_LEN_32: u16  = 0b0000_0011;
  7.  
  8. #[derive(Debug, Fail)]
  9. pub enum CodecError {
  10.     #[fail(display = "Too less bytes in the header !")]
  11.     MissingHeaderBytes,
  12.     #[fail(display = "Wrong header !")]
  13.     WrongHeader,
  14.     #[fail(display = "Invalide size len (from header) !")]
  15.     WrongSizeLen,
  16. }
  17.  
  18. #[derive(Debug, Clone, Copy)]
  19. pub enum PacketSizeEncoding {
  20.     B8,
  21.     B16,
  22.     B32,
  23.     None,
  24. }
  25.  
  26. impl From<HiHeader> for PacketSizeEncoding {
  27.     fn from(head: HiHeader) -> Self {
  28.         match head.0 & LH_SZ_LEN_ALL {
  29.             LH_SZ_LEN_8 => PacketSizeEncoding::B8,
  30.             LH_SZ_LEN_16 => PacketSizeEncoding::B16,
  31.             LH_SZ_LEN_32 => PacketSizeEncoding::B32,
  32.             _ => PacketSizeEncoding::None
  33.         }
  34.     }
  35. }
  36.  
  37. #[derive(Debug, Clone, Copy)]
  38. pub struct PacketId(u16);
  39.  
  40. impl From<HiHeader> for PacketId {
  41.     fn from(head: HiHeader) -> Self {
  42.         PacketId(head.0 >> 2)
  43.     }
  44. }
  45.  
  46. #[derive(Debug, Clone, Copy)]
  47. pub struct HiHeader(u16);
  48.  
  49. impl HiHeader {
  50.     fn header_total(&self, side: PacketSide) -> usize {
  51.         let a = match PacketSizeEncoding::from(*self) {
  52.             PacketSizeEncoding::B8 => 1,
  53.             PacketSizeEncoding::B16 => 2,
  54.             PacketSizeEncoding::B32 => 4,
  55.             _ => 0,
  56.         };
  57.         let b = match side {
  58.             Client => 6, // hi header and packet counter
  59.             Server => 2, // hi header only
  60.         };
  61.         a + b
  62.     }
  63. }
  64.  
  65. #[derive(Debug)]
  66. pub struct PacketHeader {
  67.     hi: HiHeader,
  68.     size: usize,
  69. }
  70.  
  71. impl PacketHeader {
  72.     fn from_bytes(td: &[u8], side: PacketSide) -> Result<PacketHeader, CodecError> {
  73.         if td.len() < 2 {
  74.             return Err(CodecError::MissingHeaderBytes)
  75.         }
  76.         let hi = HiHeader(u16::from_be_bytes([td[0], td[1]]));
  77.         let htotal = hi.header_total(side);
  78.         if td.len() < htotal {
  79.             return Err(CodecError::WrongHeader)
  80.         }
  81.         let size = match PacketSizeEncoding::from(hi) {
  82.             PacketSizeEncoding::B8 => usize::from(td[htotal]),
  83.             PacketSizeEncoding::B16 => usize::from(u16::from_be_bytes([ td[htotal], td[htotal + 1] ])),
  84.             PacketSizeEncoding::B32 => u32::from_be_bytes([ td[htotal], td[htotal + 1], td[htotal + 2], td[htotal + 3] ]) as usize,
  85.             PacketSizeEncoding::None => return Err(CodecError::WrongSizeLen),
  86.         };
  87.         Ok(PacketHeader {
  88.             hi,
  89.             size,
  90.         })
  91.     }
  92. }
  93.  
  94. #[derive(Debug, Clone, Copy)]
  95. pub enum PacketSide {
  96.     Client,
  97.     Server,
  98. }
  99.  
  100. pub struct DofusCodec {
  101.     buffer: Vec<u8>,
  102.     side: PacketSide,
  103. }
  104.  
  105. impl DofusCodec {
  106.     pub fn new(side: PacketSide) -> Self {
  107.         DofusCodec{buffer: Vec::new(), side}
  108.     }
  109. }
  110.  
  111. impl Write for DofusCodec {
  112.     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
  113.         let header = PacketHeader::from_bytes(buf, self.side).map(|e| {
  114.         println!("{:?} -> id: {}, len: {}", self.side, PacketId::from(e.hi).0, e.size);
  115.         e
  116.         });
  117.         Ok(buf.len())
  118.     }
  119.  
  120.     fn flush(&mut self) -> std::io::Result<()> {
  121.         Ok(())
  122.     }
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement