minecraft_pinger/java/
protocol.rs1use crate::common::protocol::{read_var_int, read_var_int_stream, write_string, write_var_int};
2use crate::error::PingError;
3use bytes::{BufMut, Bytes, BytesMut};
4use log::debug;
5use tokio::io::AsyncReadExt;
6
7pub(crate) fn write_ping_handshake(
9 buffer: &mut BytesMut,
10 hostname: &str,
11 port: &u16,
12 protocol_version: &i32,
13) {
14 let mut handshake = BytesMut::with_capacity(128);
15 handshake.put_u8(0x00);
16 write_var_int(&mut handshake, *protocol_version); write_string(&mut handshake, hostname);
18 handshake.put_u16(*port); write_var_int(&mut handshake, 1); write_var_int(buffer, handshake.len() as i32);
22 buffer.put(handshake.freeze());
23}
24
25pub(crate) fn write_ping_request(buffer: &mut BytesMut) {
26 write_var_int(buffer, 1); write_var_int(buffer, 0x00); }
29
30pub(crate) struct Packet {
31 id: u8,
32 pub data: Bytes,
33}
34
35impl Packet {
36 pub fn new(id: u8, data: Bytes) -> Packet {
37 Packet { id, data }
38 }
39
40 pub fn id(&self) -> u8 {
41 self.id
42 }
43}
44
45pub(crate) async fn read_packet<R: AsyncReadExt + Unpin>(
46 stream: &mut R,
47) -> Result<Packet, PingError> {
48 let length = read_var_int_stream(stream).await?;
49
50 let mut buf = vec![0u8; length as usize];
52 stream.read_exact(&mut buf).await.map_err(|e| {
53 debug!("Read packet error 2 {e}");
54 PingError::ReadPacket(e.to_string())
55 })?;
56
57 let mut data = Bytes::from(buf);
58
59 Ok(Packet::new(read_var_int(&mut data)? as u8, data))
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use bytes::BytesMut;
66 use tokio::io::BufReader;
67
68 #[test]
69 fn test_write_ping_handshake() {
70 let mut buffer = BytesMut::new();
71 write_ping_handshake(&mut buffer, "example.com", &25565, &775);
72
73 assert!(!buffer.is_empty());
75
76 let mut data = buffer.clone().freeze();
78 let length = read_var_int(&mut data).unwrap();
79 assert_eq!(length as usize, data.len());
80 }
81
82 #[test]
83 fn test_write_ping_request() {
84 let mut buffer = BytesMut::new();
85 write_ping_request(&mut buffer);
86
87 let mut data = buffer.freeze();
88 let length = read_var_int(&mut data).unwrap();
89 assert_eq!(length, 1); let packet_id = read_var_int(&mut data).unwrap();
92 assert_eq!(packet_id, 0x00); }
94
95 #[test]
96 fn test_packet_new_and_id() {
97 let packet = Packet::new(0x01, Bytes::from_static(b"test"));
98 assert_eq!(packet.id(), 0x01);
99 }
100
101 #[tokio::test]
102 async fn test_read_packet_valid() {
103 let mut buffer = BytesMut::new();
104 write_ping_request(&mut buffer);
105 let data = buffer.freeze();
106
107 let mut reader = BufReader::new(&data[..]);
108 let packet = read_packet(&mut reader).await.unwrap();
109
110 assert_eq!(packet.id(), 0x00);
111 }
112
113 #[tokio::test]
114 async fn test_read_packet_invalid_length() {
115 let data = Bytes::from_static(&[
116 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01,
117 ]);
118 let mut reader = BufReader::new(&data[..]);
119 let result = read_packet(&mut reader).await;
120 assert!(result.is_err());
121 }
122}