kojacoord_protocol/versions/v1_6_4/handshake/
mod.rs1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::codec::{Decode, Encode, PacketId};
4use crate::error::ProtocolError;
5
6fn decode_legacy_string(src: &mut Bytes) -> Result<String, ProtocolError> {
7 if src.len() < 2 {
8 return Err(ProtocolError::UnexpectedEof);
9 }
10 let len = u16::from_be_bytes([src[0], src[1]]) as usize;
11 src.advance(2);
12 let byte_len = len * 2;
13 if src.len() < byte_len {
14 return Err(ProtocolError::UnexpectedEof);
15 }
16 let raw = src.copy_to_bytes(byte_len);
17 let chars: Vec<u16> = raw
18 .chunks(2)
19 .map(|c| u16::from_be_bytes([c[0], c[1]]))
20 .collect();
21 String::from_utf16(&chars).map_err(|_| ProtocolError::UnexpectedEof)
22}
23
24fn encode_legacy_string(s: &str, dst: &mut BytesMut) {
25 let utf16: Vec<u16> = s.encode_utf16().collect();
26 dst.extend_from_slice(&(utf16.len() as u16).to_be_bytes());
27 for ch in &utf16 {
28 dst.extend_from_slice(&ch.to_be_bytes());
29 }
30}
31
32#[derive(Debug, Clone, PartialEq)]
33pub struct ServerboundHandshake {
34 pub protocol_version: u8,
35 pub username: String,
36 pub host: String,
37 pub port: i32,
38}
39
40impl PacketId for ServerboundHandshake {
41 fn packet_id(_ver: u32) -> u8 {
42 0x02
43 }
44}
45
46impl Encode for ServerboundHandshake {
47 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
48 dst.put_u8(self.protocol_version);
49 encode_legacy_string(&self.username, dst);
50 encode_legacy_string(&self.host, dst);
51 dst.put_i32(self.port);
52 Ok(())
53 }
54}
55
56impl Decode for ServerboundHandshake {
57 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
58 let protocol_version = src.get_u8();
59 let username = decode_legacy_string(src)?;
60 let host = decode_legacy_string(src)?;
61 let port = src.get_i32();
62 Ok(Self {
63 protocol_version,
64 username,
65 host,
66 port,
67 })
68 }
69}