use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use serde::{Deserialize, Serialize};
use std::io::{self, Cursor, Write};
use crate::{
errors::ParseError,
packet::{
header::{Header, PacketFrequency},
packet::{Packet, PacketData},
packet_types::PacketType,
},
};
impl Packet {
pub fn new_coarse_location_update(coarse_location_update: CoarseLocationUpdate) -> Self {
Packet {
header: Header {
id: 6,
frequency: PacketFrequency::Medium,
reliable: false,
zerocoded: false,
..Default::default()
},
body: PacketType::CoarseLocationUpdate(Box::new(coarse_location_update)),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MinimapEntities {
x: u8,
y: u8,
z: u8,
}
impl MinimapEntities {
pub fn from_bytes(bytes: &[u8], i: &mut usize) -> io::Result<Self> {
let cursor = Cursor::new(&bytes[*i..]);
let x = cursor.get_ref()[0];
let y = cursor.get_ref()[1];
let z = cursor.get_ref()[2];
*i += 3; Ok(Self { x, y, z })
}
pub fn to_bytes(&self, bytes: &mut [u8], i: &mut usize) -> io::Result<()> {
let mut cursor = Cursor::new(&mut bytes[*i..]);
cursor.write_all(&[self.x, self.y, self.z])?;
*i += 3; Ok(())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoarseLocationUpdate {
pub locations: Vec<MinimapEntities>,
pub you: i16,
pub prey: i16,
}
impl PacketData for CoarseLocationUpdate {
fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError> {
let mut cursor = Cursor::new(bytes);
let location_count = cursor.read_u8()? as usize;
let mut locations = Vec::with_capacity(location_count);
for _ in 0..location_count {
let x = cursor.read_u8()?;
let y = cursor.read_u8()?;
let z = cursor.read_u8()?;
locations.push(MinimapEntities { x, y, z });
}
let you = cursor.read_i16::<LittleEndian>()?;
let prey = cursor.read_i16::<LittleEndian>()?;
Ok(CoarseLocationUpdate {
locations,
you,
prey,
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(self.locations.len() as u8);
for location in &self.locations {
bytes.push(location.x);
bytes.push(location.y);
bytes.push(location.z);
}
bytes.write_i16::<LittleEndian>(self.you).unwrap();
bytes.write_i16::<LittleEndian>(self.prey).unwrap();
bytes
}
}