Skip to main content

mc_gate/mc/
mod.rs

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}