kojacoord_protocol/versions/v1_16_5/status/
mod.rs1use 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}