use std::sync::Mutex; use crate::types; pub const STATUS_PACKET_ID_STATUS: i32 = 0; pub const STATUS_PACKET_ID_PING: i32 = 1; /// Client state. // TODO: add encryption/compression state #[derive(Debug, Default)] pub struct Client { /// Current client state. pub state: Mutex, } impl Client { /// Get client state. pub fn state(&self) -> ClientState { *self.state.lock().unwrap() } /// Set client state. pub fn set_state(&self, state: ClientState) { *self.state.lock().unwrap() = state; } } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum ClientState { /// Initial client state. Handshake, /// State to query server status. Status, /// State to login to server. Login, /// State for playing. Play, } impl ClientState { /// From state ID. pub fn from_id(id: i32) -> Option { match id { // 0 => Self::Handshake, 1 => Some(Self::Status), 2 => Some(Self::Login), // 2 => Self::Play, _ => None, } } /// Get state ID. pub fn to_id(self) -> i32 { match self { Self::Handshake => unimplemented!(), Self::Status => 1, Self::Login => 2, Self::Play => unimplemented!(), } } } impl Default for ClientState { fn default() -> Self { Self::Handshake } } /// Raw Minecraft packet. /// /// Having a packet ID and a raw data byte array. pub struct RawPacket { /// Packet ID. pub id: i32, /// Packet data. pub data: Vec, } impl RawPacket { /// Construct new raw packet. pub fn new(id: i32, data: Vec) -> Self { Self { id, data } } /// Decode packet from raw buffer. pub fn decode(mut buf: &[u8]) -> Result { // Read length let (read, len) = types::read_var_int(buf)?; buf = &buf[read..][..len as usize]; Self::decode_data(len, buf) } /// Decode packet from raw buffer without the length header. pub fn decode_data(len: i32, mut buf: &[u8]) -> Result { // Read packet ID, select buf let (read, packet_id) = types::read_var_int(buf)?; buf = &buf[read..]; Ok(Self::new(packet_id, buf.to_vec())) } /// Encode packet to raw buffer. pub fn encode(&self) -> Result, ()> { let mut data = types::encode_var_int(self.id)?; data.extend_from_slice(&self.data); let len = data.len() as i32; let mut packet = types::encode_var_int(len)?; packet.append(&mut data); return Ok(packet); } }