Skip to main content

minecraft_pinger/java/
protocol.rs

1use 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
7// Packets
8pub(crate) fn write_ping_handshake(buffer: &mut BytesMut, hostname: &str, port: &u16, protocol_version: &i32) {
9    let mut handshake = BytesMut::with_capacity(128);
10    handshake.put_u8(0x00);
11    write_var_int(&mut handshake, *protocol_version); // protocol version
12    write_string(&mut handshake, hostname);
13    handshake.put_u16(*port); // Server Port
14    write_var_int(&mut handshake, 1); // next state = 1 status
15
16    write_var_int(buffer, handshake.len() as i32);
17    buffer.put(handshake.freeze());
18}
19
20pub(crate) fn write_ping_request(buffer: &mut BytesMut) {
21    write_var_int(buffer, 1); // length
22    write_var_int(buffer, 0x00); // packet id
23}
24
25pub(crate) struct Packet {
26    id: u8,
27    pub data: Bytes,
28}
29
30impl Packet {
31    pub fn new(id: u8, data: Bytes) -> Packet {
32        Packet { id, data }
33    }
34
35    pub fn id(&self) -> u8 {
36        self.id
37    }
38}
39
40pub(crate) async fn read_packet<R: AsyncReadExt + Unpin>(stream: &mut R) -> Result<Packet, PingError> {
41    let length = read_var_int_stream(stream).await?;
42
43    // Lire exactement `length` bytes
44    let mut buf = vec![0u8; length as usize];
45    stream.read_exact(&mut buf)
46        .await
47        .map_err(|e| {
48            debug!("Read packet error 2 {e}");
49            PingError::ReadPacket(e.to_string())
50        })?;
51
52    let mut data = Bytes::from(buf);
53
54    Ok(Packet::new(read_var_int(&mut data)? as u8, data))
55}