1use serde::Serialize;
2use std::io::Cursor;
3use tokio::io::AsyncReadExt;
4use tokio::net::TcpStream;
5
6pub mod codec;
7pub mod handler;
8
9#[derive(Serialize)]
10pub struct StatusResponse {
11 pub version: Version,
12 pub players: Players,
13 pub description: Description,
14}
15
16#[derive(Serialize)]
17pub struct Version {
18 pub name: String,
19 pub protocol: i32,
20}
21
22#[derive(Serialize)]
23pub struct Players {
24 pub max: i32,
25 pub online: String,
26}
27
28#[derive(Serialize)]
29pub struct Description {
30 pub text: String,
31}
32
33#[derive(Serialize)]
34pub struct DisconnectResponse {
35 pub text: String,
36}
37
38pub struct MinecraftPacket {
39 pub id: i32,
40 pub data: Vec<u8>,
41}
42
43impl MinecraftPacket {
44 pub async fn send_json<S: tokio::io::AsyncWriteExt + Unpin, T: serde::Serialize>(
45 stream: &mut S,
46 id: i32,
47 payload: &T,
48 ) -> tokio::io::Result<()> {
49 let json = serde_json::to_string(payload)
50 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
51 let mut data = Vec::new();
52 codec::write_string(&mut data, &json);
53 let packet = Self { id, data }.serialize();
54 stream.write_all(&packet).await?;
55 stream.flush().await
56 }
57
58 pub fn serialize(self) -> Vec<u8> {
59 let mut body = Vec::new();
60 codec::write_varint(&mut body, self.id);
61 body.extend(self.data);
62
63 let mut frame = Vec::new();
64 codec::write_varint(&mut frame, body.len() as i32);
65 frame.extend(body);
66 frame
67 }
68}
69
70pub async fn inspect_handshake(socket: &TcpStream) -> i32 {
71 let mut buf = [0u8; 128];
72 if let Ok(n) = socket.peek(&mut buf[..]).await {
73 let mut cur = Cursor::new(&buf[..n]);
74 let _ = codec::read_varint(&mut cur).await;
75 if let Ok(0x00) = codec::read_varint(&mut cur).await {
76 let _ = codec::read_varint(&mut cur).await;
77 let _ = codec::read_string(&mut cur).await;
78 let _ = cur.read_u16().await;
79 return codec::read_varint(&mut cur).await.unwrap_or(1);
80 }
81 }
82 1
83}