mirror of
https://github.com/timvisee/lazymc.git
synced 2025-07-26 09:42:03 -07:00
119 lines
2.6 KiB
Rust
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);
|
|
}
|
|
}
|