Skip to main content

kojacoord_protocol/versions/v1_16_5/status/
mod.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::codec::{Decode, Encode, PacketId};
4use crate::error::ProtocolError;
5use crate::types::VarInt;
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct ServerboundStatusRequest;
9
10impl PacketId for ServerboundStatusRequest {
11    fn packet_id(_ver: u32) -> u8 {
12        0x00
13    }
14}
15
16impl Encode for ServerboundStatusRequest {
17    fn encode(&self, _dst: &mut BytesMut) -> Result<(), ProtocolError> {
18        Ok(())
19    }
20}
21
22impl Decode for ServerboundStatusRequest {
23    fn decode(_src: &mut Bytes) -> Result<Self, ProtocolError> {
24        Ok(Self)
25    }
26}
27
28#[derive(Debug, Clone, PartialEq)]
29pub struct ClientboundStatusResponse {
30    pub json_response: String,
31}
32
33impl PacketId for ClientboundStatusResponse {
34    fn packet_id(_ver: u32) -> u8 {
35        0x00
36    }
37}
38
39impl Encode for ClientboundStatusResponse {
40    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
41        let bytes = self.json_response.as_bytes();
42        VarInt(bytes.len() as i32).encode(dst)?;
43        dst.put_slice(bytes);
44        Ok(())
45    }
46}
47
48impl Decode for ClientboundStatusResponse {
49    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
50        let len = VarInt::decode(src)?.0 as usize;
51        if src.remaining() < len {
52            return Err(ProtocolError::Io(std::io::Error::new(
53                std::io::ErrorKind::UnexpectedEof,
54                "Missing bytes for ClientboundStatusResponse json_response",
55            )));
56        }
57        let mut buf = vec![0u8; len];
58        src.copy_to_slice(&mut buf);
59        let json_response = String::from_utf8(buf).map_err(|_| {
60            ProtocolError::Io(std::io::Error::new(
61                std::io::ErrorKind::InvalidData,
62                "Invalid UTF-8 in ClientboundStatusResponse json_response",
63            ))
64        })?;
65        Ok(Self { json_response })
66    }
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub struct ServerboundPingRequest {
71    pub payload: i64,
72}
73
74impl PacketId for ServerboundPingRequest {
75    fn packet_id(_ver: u32) -> u8 {
76        0x01
77    }
78}
79
80impl Encode for ServerboundPingRequest {
81    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
82        dst.put_i64(self.payload);
83        Ok(())
84    }
85}
86
87impl Decode for ServerboundPingRequest {
88    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
89        if src.remaining() < 8 {
90            return Err(ProtocolError::Io(std::io::Error::new(
91                std::io::ErrorKind::UnexpectedEof,
92                "Missing bytes for ServerboundPingRequest payload",
93            )));
94        }
95        Ok(Self {
96            payload: src.get_i64(),
97        })
98    }
99}
100
101#[derive(Debug, Clone, PartialEq)]
102pub struct ClientboundPongResponse {
103    pub payload: i64,
104}
105
106impl PacketId for ClientboundPongResponse {
107    fn packet_id(_ver: u32) -> u8 {
108        0x01
109    }
110}
111
112impl Encode for ClientboundPongResponse {
113    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
114        dst.put_i64(self.payload);
115        Ok(())
116    }
117}
118
119impl Decode for ClientboundPongResponse {
120    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
121        if src.remaining() < 8 {
122            return Err(ProtocolError::Io(std::io::Error::new(
123                std::io::ErrorKind::UnexpectedEof,
124                "Missing bytes for ClientboundPongResponse payload",
125            )));
126        }
127        Ok(Self {
128            payload: src.get_i64(),
129        })
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn status_request_roundtrip() {
139        let mut buf = BytesMut::new();
140        ServerboundStatusRequest.encode(&mut buf).unwrap();
141        let mut b = buf.freeze();
142        assert_eq!(
143            ServerboundStatusRequest::decode(&mut b).unwrap(),
144            ServerboundStatusRequest
145        );
146    }
147
148    #[test]
149    fn response_roundtrip() {
150        let p = ClientboundStatusResponse {
151            json_response: "{}".to_string(),
152        };
153        let mut buf = BytesMut::new();
154        p.encode(&mut buf).unwrap();
155        let mut b = buf.freeze();
156        assert_eq!(ClientboundStatusResponse::decode(&mut b).unwrap(), p);
157    }
158
159    #[test]
160    fn ping_roundtrip() {
161        let p = ServerboundPingRequest { payload: 99 };
162        let mut buf = BytesMut::new();
163        p.encode(&mut buf).unwrap();
164        let mut b = buf.freeze();
165        assert_eq!(ServerboundPingRequest::decode(&mut b).unwrap(), p);
166    }
167
168    #[test]
169    fn pong_roundtrip() {
170        let p = ClientboundPongResponse { payload: -1 };
171        let mut buf = BytesMut::new();
172        p.encode(&mut buf).unwrap();
173        let mut b = buf.freeze();
174        assert_eq!(ClientboundPongResponse::decode(&mut b).unwrap(), p);
175    }
176}