Skip to main content

kojacoord_protocol/versions/v1_16_5/handshake/
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 ServerboundHandshake {
9    pub protocol_version: VarInt,
10    pub server_address: String,
11    pub server_port: u16,
12    pub next_state: VarInt,
13}
14
15impl PacketId for ServerboundHandshake {
16    fn packet_id(_ver: u32) -> u8 {
17        0x00
18    }
19}
20
21impl Encode for ServerboundHandshake {
22    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
23        self.protocol_version.encode(dst)?;
24
25        let addr_bytes = self.server_address.as_bytes();
26        VarInt(addr_bytes.len() as i32).encode(dst)?;
27        dst.put_slice(addr_bytes);
28
29        dst.put_u16(self.server_port);
30
31        self.next_state.encode(dst)
32    }
33}
34
35impl Decode for ServerboundHandshake {
36    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
37        let protocol_version = VarInt::decode(src)?;
38
39        let addr_len = VarInt::decode(src)?.0 as usize;
40        if src.remaining() < addr_len {
41            return Err(ProtocolError::Io(std::io::Error::new(
42                std::io::ErrorKind::UnexpectedEof,
43                "Missing bytes for ServerboundHandshake server_address",
44            )));
45        }
46        let mut addr_bytes = vec![0u8; addr_len];
47        src.copy_to_slice(&mut addr_bytes);
48        let server_address = String::from_utf8(addr_bytes).map_err(|_| {
49            ProtocolError::Io(std::io::Error::new(
50                std::io::ErrorKind::InvalidData,
51                "Invalid UTF-8 in ServerboundHandshake server_address",
52            ))
53        })?;
54
55        if src.remaining() < 2 {
56            return Err(ProtocolError::Io(std::io::Error::new(
57                std::io::ErrorKind::UnexpectedEof,
58                "Missing bytes for ServerboundHandshake server_port",
59            )));
60        }
61        let server_port = src.get_u16();
62
63        let next_state = VarInt::decode(src)?;
64
65        Ok(Self {
66            protocol_version,
67            server_address,
68            server_port,
69            next_state,
70        })
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn roundtrip() {
80        let p = ServerboundHandshake {
81            protocol_version: VarInt(754),
82            server_address: "play.example.com".to_string(),
83            server_port: 25565,
84            next_state: VarInt(2),
85        };
86        let mut buf = BytesMut::new();
87        p.encode(&mut buf).unwrap();
88        let mut b = buf.freeze();
89        assert_eq!(ServerboundHandshake::decode(&mut b).unwrap(), p);
90    }
91}