1mod args;
3mod commands;
4mod config;
5mod consts;
6mod fs_manager;
7mod logging;
8mod net;
9use log::{error, info, warn};
10use net::packet;
11use std::net::Ipv4Addr;
12mod greetings;
13mod handlers;
14mod player;
15mod shutdown;
16mod time;
17use config::Gamemode;
18use consts::messages;
19#[tokio::main]
20async fn main() {
21 if let Err(e) = early_init().await {
22 error!("Failed to start the server, error in early initialization: {e}. \nExiting...");
23 gracefully_exit(ExitCode::Failure);
24 }
25
26 if let Err(e) = init() {
27 error!("Failed to start the server, error in initialization: {e}. \nExiting...");
28 gracefully_exit(ExitCode::Failure);
29 }
30
31 if let Err(e) = start().await {
32 error!("Failed to start the server: {e}. \nExiting...");
33 gracefully_exit(ExitCode::Failure);
34 }
35
36 info!("{}", *messages::SERVER_SHUTDOWN_SUCCESS);
37}
38#[cfg(debug_assertions)]
39const DISABLE_LOGGING_COLOR_AND_SAVE_TO_FILE: bool = false;
40
41#[cfg(not(debug_assertions))]
42const DISABLE_LOGGING_COLOR_AND_SAVE_TO_FILE: bool = true;
43async fn early_init() -> Result<(), Box<dyn std::error::Error>> {
45 logging::init(
47 log::LevelFilter::Debug,
48 DISABLE_LOGGING_COLOR_AND_SAVE_TO_FILE,
49 );
50
51 args::init();
52
53 info!("{}", *messages::SERVER_STARTING);
54
55 handlers::init_ctrlc_handler()?;
57 #[cfg(debug_assertions)]
59 test();
60
61 commands::listen_console_commands().await;
63 Ok(())
64}
65
66fn init() -> Result<(), Box<dyn std::error::Error>> {
68 greetings::greet();
70
71 vec![
72 || fs_manager::init(),
73 || Ok(fs_manager::create_dirs()),
74 || Ok(fs_manager::create_other_files()),
75 ]
76 .iter()
77 .try_for_each(|task| task())?;
78
79 let gamemode1 = match config::Settings::new().gamemode {
80 Gamemode::Survival => "Survival",
81 Gamemode::Adventure => "Adventure",
82 Gamemode::Creative => "Creative",
83 Gamemode::Spectator => "Spectator",
84 };
85 info!("Default game type: {}", gamemode1.to_uppercase());
86
87 Ok(())
88}
89
90async fn start() -> Result<(), Box<dyn std::error::Error>> {
92 info!(
93 "Starting Minecraft server on {}:{}",
94 config::Settings::new()
95 .server_ip
96 .unwrap_or(Ipv4Addr::new(0, 0, 0, 0)), config::Settings::new().server_port
98 );
99 info!("{}", *messages::SERVER_STARTED);
100
101 net::listen().await?;
102
103 Ok(())
104}
105
106#[cfg(debug_assertions)]
107fn test() {
109 info!("[ BEGIN test() ]");
110
111 let _ = packet::Packet::new(&[]);
114
115 info!("[ END test()]");
116}
117
118pub enum ExitCode {
120 Success,
121 Failure,
122 CtrlC,
123}
124
125pub fn gracefully_exit(exit_code: ExitCode) -> ! {
127 let numerical_exit_code: i32 = match exit_code {
128 ExitCode::Success => {
129 info!("{}", *messages::SERVER_SHUTDOWN_SUCCESS);
130 0
132 }
133 ExitCode::Failure => {
134 warn!("{}", *messages::SERVER_SHUTDOWN_ERROR);
135 1
137 }
138 ExitCode::CtrlC => {
139 info!("{}", *messages::SERVER_SHUTDOWN_CTRL_C);
140 130
142 }
143 };
144
145 std::process::exit(numerical_exit_code);
147}