Files
lazymc/src/protocol.rs
2021-11-07 17:20:06 +01:00

119 lines
2.6 KiB
Rust

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<ClientState>,
}
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<Self> {
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<u8>,
}
impl RawPacket {
/// Construct new raw packet.
pub fn new(id: i32, data: Vec<u8>) -> Self {
Self { id, data }
}
/// Decode packet from raw buffer.
pub fn decode(mut buf: &[u8]) -> Result<Self, ()> {
// 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<Self, ()> {
// 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<Vec<u8>, ()> {
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);
}
}