kojacoord_protocol/versions/v1_16_5/handshake/
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 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}