use crate::common::protocol::{read_var_int, read_var_int_stream, write_string, write_var_int};
use crate::error::PingError;
use bytes::{BufMut, Bytes, BytesMut};
use log::debug;
use tokio::io::AsyncReadExt;
pub(crate) fn write_ping_handshake(buffer: &mut BytesMut, hostname: &str, port: &u16, protocol_version: &i32) {
let mut handshake = BytesMut::with_capacity(128);
handshake.put_u8(0x00);
write_var_int(&mut handshake, *protocol_version); write_string(&mut handshake, hostname);
handshake.put_u16(*port); write_var_int(&mut handshake, 1);
write_var_int(buffer, handshake.len() as i32);
buffer.put(handshake.freeze());
}
pub(crate) fn write_ping_request(buffer: &mut BytesMut) {
write_var_int(buffer, 1); write_var_int(buffer, 0x00); }
pub(crate) struct Packet {
id: u8,
pub data: Bytes,
}
impl Packet {
pub fn new(id: u8, data: Bytes) -> Packet {
Packet { id, data }
}
pub fn id(&self) -> u8 {
self.id
}
}
pub(crate) async fn read_packet<R: AsyncReadExt + Unpin>(stream: &mut R) -> Result<Packet, PingError> {
let length = read_var_int_stream(stream).await?;
let mut buf = vec![0u8; length as usize];
stream.read_exact(&mut buf)
.await
.map_err(|e| {
debug!("Read packet error 2 {e}");
PingError::ReadPacket(e.to_string())
})?;
let mut data = Bytes::from(buf);
Ok(Packet::new(read_var_int(&mut data)? as u8, data))
}