Skip to main content

kojacoord_protocol/versions/v1_12_2/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 json_bytes = self.json_response.as_bytes();
42        VarInt(json_bytes.len() as i32).encode(dst)?;
43        dst.put_slice(json_bytes);
44        Ok(())
45    }
46}
47
48impl Decode for ClientboundStatusResponse {
49    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
50        let json_len = VarInt::decode(src)?.0 as usize;
51
52        if src.remaining() < json_len {
53            return Err(ProtocolError::Io(std::io::Error::new(
54                std::io::ErrorKind::UnexpectedEof,
55                "Missing bytes while reading ClientboundStatusResponse JSON payload",
56            )));
57        }
58
59        let mut json_bytes = vec![0u8; json_len];
60        src.copy_to_slice(&mut json_bytes);
61
62        let json_response = String::from_utf8(json_bytes).map_err(|_| {
63            ProtocolError::Io(std::io::Error::new(
64                std::io::ErrorKind::InvalidData,
65                "Invalid UTF-8 string in ClientboundStatusResponse",
66            ))
67        })?;
68
69        Ok(Self { json_response })
70    }
71}
72
73#[derive(Debug, Clone, PartialEq)]
74pub struct ServerboundPingRequest {
75    pub payload: i64,
76}
77
78impl PacketId for ServerboundPingRequest {
79    fn packet_id(_ver: u32) -> u8 {
80        0x01
81    }
82}
83
84impl Encode for ServerboundPingRequest {
85    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
86        dst.put_i64(self.payload);
87        Ok(())
88    }
89}
90
91impl Decode for ServerboundPingRequest {
92    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
93        if src.remaining() < 8 {
94            return Err(ProtocolError::Io(std::io::Error::new(
95                std::io::ErrorKind::UnexpectedEof,
96                "Missing bytes for ServerboundPingRequest payload",
97            )));
98        }
99        Ok(Self {
100            payload: src.get_i64(),
101        })
102    }
103}
104
105#[derive(Debug, Clone, PartialEq)]
106pub struct ClientboundPongResponse {
107    pub payload: i64,
108}
109
110impl PacketId for ClientboundPongResponse {
111    fn packet_id(_ver: u32) -> u8 {
112        0x01
113    }
114}
115
116impl Encode for ClientboundPongResponse {
117    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
118        dst.put_i64(self.payload);
119        Ok(())
120    }
121}
122
123impl Decode for ClientboundPongResponse {
124    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
125        if src.remaining() < 8 {
126            return Err(ProtocolError::Io(std::io::Error::new(
127                std::io::ErrorKind::UnexpectedEof,
128                "Missing bytes for ClientboundPongResponse payload",
129            )));
130        }
131        Ok(Self {
132            payload: src.get_i64(),
133        })
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn response_roundtrip() {
143        let p = ClientboundStatusResponse {
144            json_response: "{}".to_string(),
145        };
146        let mut buf = BytesMut::new();
147        p.encode(&mut buf).unwrap();
148        let mut b = buf.freeze();
149        assert_eq!(ClientboundStatusResponse::decode(&mut b).unwrap(), p);
150    }
151
152    #[test]
153    fn ping_roundtrip() {
154        let p = ServerboundPingRequest { payload: 42 };
155        let mut buf = BytesMut::new();
156        p.encode(&mut buf).unwrap();
157        let mut b = buf.freeze();
158        assert_eq!(ServerboundPingRequest::decode(&mut b).unwrap(), p);
159    }
160}