deepslate-protocol 0.1.0

Minecraft protocol primitives for the Deepslate proxy.
Documentation
//! Status (server list ping) packets.

use bytes::{Buf, BufMut};

use crate::types::{self, ProtocolError};

use super::Packet;

/// Serverbound status request (packet ID 0x00 in STATUS state).
/// This packet has no fields.
#[derive(Debug, Clone)]
pub struct StatusRequestPacket;

impl Packet for StatusRequestPacket {
    const PACKET_ID: i32 = 0x00;

    fn decode(_buf: &mut impl Buf) -> Result<Self, ProtocolError> {
        Ok(Self)
    }

    fn encode(&self, _buf: &mut impl BufMut) {}
}

/// Clientbound status response (packet ID 0x00 in STATUS state).
#[derive(Debug, Clone)]
pub struct StatusResponsePacket {
    /// JSON string containing the server status.
    pub json: String,
}

impl Packet for StatusResponsePacket {
    const PACKET_ID: i32 = 0x00;

    fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
        let json = types::read_string(buf)?;
        Ok(Self { json })
    }

    fn encode(&self, buf: &mut impl BufMut) {
        types::write_string(buf, &self.json);
    }
}

/// Serverbound ping request (packet ID 0x01 in STATUS state).
#[derive(Debug, Clone)]
pub struct PingRequestPacket {
    /// Arbitrary payload echoed by the server.
    pub payload: i64,
}

impl Packet for PingRequestPacket {
    const PACKET_ID: i32 = 0x01;

    fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
        if buf.remaining() < 8 {
            return Err(ProtocolError::UnexpectedEof);
        }
        Ok(Self {
            payload: buf.get_i64(),
        })
    }

    fn encode(&self, buf: &mut impl BufMut) {
        buf.put_i64(self.payload);
    }
}

/// Clientbound pong response (packet ID 0x01 in STATUS state).
#[derive(Debug, Clone)]
pub struct PongResponsePacket {
    /// The payload echoed from the ping request.
    pub payload: i64,
}

impl Packet for PongResponsePacket {
    const PACKET_ID: i32 = 0x01;

    fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
        if buf.remaining() < 8 {
            return Err(ProtocolError::UnexpectedEof);
        }
        Ok(Self {
            payload: buf.get_i64(),
        })
    }

    fn encode(&self, buf: &mut impl BufMut) {
        buf.put_i64(self.payload);
    }
}