use crate::{Error, payload::{Decode, Encode}, Payload}; use std::io::{Read, Seek, SeekFrom}; use crate::payload::{SeStringChunkKind, SeInteractableKind}; #[derive(Debug, Clone, PartialEq)] pub struct PlayerPayload { pub server_id: u32, pub name: String, } impl Decode for PlayerPayload { fn decode(mut reader: R, _chunk_len: usize) -> Result { reader.seek(SeekFrom::Current(1)).map_err(Error::from)?; // unk let server_id = Self::read_integer(&mut reader)?; reader.seek(SeekFrom::Current(2)).map_err(Error::from)?; // unk let name_len = Self::read_integer(&mut reader)?; let mut name_bytes = vec![0; name_len as usize]; reader.read_exact(&mut name_bytes).map_err(Error::from)?; let name = String::from_utf8(name_bytes).map_err(Error::from)?; Ok(Self { server_id, name, }) } } impl Encode for PlayerPayload { fn encode(&self) -> Vec { use std::iter::once; let name = self.name.as_bytes(); let name_len = Self::make_integer(name.len() as u32); let server = Self::make_integer(self.server_id); let chunk_len = name.len() + server.len() + name_len.len() + 5; once(Payload::START_BYTE) .chain(once(SeStringChunkKind::Interactable.as_u8())) .chain(once(chunk_len as u8)) .chain(once(SeInteractableKind::PlayerName.as_u8())) .chain(once(0x01)) .chain(server.into_iter()) .chain(once(0x01)) .chain(once(0xFF)) .chain(name_len.into_iter()) .chain(name.iter().copied()) .chain(once(Payload::END_BYTE)) .collect() } }