status_server/
status_server.rs

1use std::{net::TcpListener, sync::Arc, thread};
2use rust_mc_proto::{prelude::*, MCConnTcp, MinecraftConnection, Packet, ProtocolError};
3
4/*
5
6    Example of simple server that sends motd 
7    to client like a vanilla minecraft server
8
9*/
10
11struct MinecraftServer {
12    server_ip: String,
13    server_port: u16,
14    motd: String
15}
16
17impl MinecraftServer {
18    fn new(server_ip: &str,
19            server_port: u16,
20            motd: &str) -> Self {
21        MinecraftServer {
22            server_ip: server_ip.to_string(),
23            server_port,
24            motd: motd.to_string()
25        }
26    }
27
28    fn start(self) {
29        let addr = self.server_ip.clone() + ":" + &self.server_port.to_string();
30        let listener = TcpListener::bind(addr).unwrap();
31
32        let this = Arc::new(self);
33
34        for stream in listener.incoming() {
35            let stream = stream.unwrap();
36
37            thread::spawn({
38                let this = this.clone();
39
40                move || {
41                    Self::accept_client(this, MinecraftConnection::new(stream)).unwrap();
42                }
43            });
44        }
45    }
46
47    fn accept_client(self: Arc<Self>, mut conn: MCConnTcp) -> Result<(), ProtocolError> {
48        let mut handshake = false;
49        
50        loop {
51            let Ok(mut packet) = conn.read_packet() else { break; };
52    
53            if handshake {
54                if packet.id() == 0x00 {
55                    let motd = self.motd.clone();
56
57                    conn.write_packet(&Packet::build(0x00, |status| 
58                        status.write_string(&motd)
59                    )?)?;
60                } else if packet.id() == 0x01 {
61                    conn.write_packet(&Packet::build(0x01, |status| 
62                        status.write_long(packet.read_long()?)
63                    )?)?;
64                }
65            } else if packet.id() == 0x00 {
66                let protocol_version = packet.read_varint()?;
67                let server_address = packet.read_string()?;
68                let server_port = packet.read_unsigned_short()?;
69                let next_state = packet.read_varint()?;
70    
71                if next_state != 1 { break; }
72    
73                println!(
74                    "{} > protocol: {} server: {}:{}", 
75                    conn.get_ref().peer_addr().unwrap(), 
76                    protocol_version, 
77                    server_address, 
78                    server_port
79                );
80    
81                handshake = true;
82            } else {
83                break;
84            }
85        }
86    
87        conn.close();
88    
89        Ok(())
90    }
91}
92
93fn main() {
94    let server = MinecraftServer::new(
95        "127.0.0.1", 
96        25565, 
97        "{
98            \"version\":{
99                \"protocol\":765,
100                \"name\":\"Version name\"
101            },
102            \"players\":{
103                \"online\":0,
104                \"max\":1,
105                \"sample\":[
106                    {
107                        \"uuid\": \"\",
108                        \"name\": \"Notch\"
109                    }
110                ]
111            },
112            \"description\": {
113                \"text\": \"Hello World!\",
114                \"color\": \"red\",
115                \"bold\": true
116            },
117            \"favicon\": \"data:image/png;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=\"
118        }"
119    );
120
121    server.start();
122}