1#[macro_use]
2extern crate lazy_static;
3
4pub mod entity;
6pub mod mctypes;
8pub mod server;
10pub mod world;
12
13use log::*;
14pub use mctypes::*;
15use serde::{Deserialize, Serialize};
16use std::sync::mpsc::{self, Receiver};
17
18#[derive(Serialize, Deserialize)]
19pub struct Config {
20 pub port: u16,
21 pub max_players: usize,
22 pub motd: String,
23 pub favicon: String,
24}
25
26lazy_static! {
27 static ref CONFIG: Config = {
28 let config_from_file = || -> std::io::Result<Config> {
29 use std::{fs::File, io::prelude::*};
30 let mut data = String::new();
31 let mut file = File::open("composition.toml")?;
32 file.read_to_string(&mut data)?;
33 if let Ok(c) = toml::from_str::<Config>(&data) {
34 Ok(c)
35 } else {
36 Err(std::io::Error::new(
37 std::io::ErrorKind::Other,
38 "Could not parse toml",
39 ))
40 }
41 };
42 if let Ok(c) = config_from_file() {
43 c
44 } else {
45 warn!("Could not load config from file, using default");
46 Config {
47 port: 25565,
48 max_players: 20,
49 motd: "Hello world!".to_owned(),
50 favicon: "server-icon.png".to_owned(),
51 }
52 }
53 };
54 static ref FAVICON: std::io::Result<Vec<u8>> = {
55 use std::{fs::File, io::prelude::*};
56 let mut data = vec![];
57 let mut file = File::open(CONFIG.favicon.clone())?;
58 file.read_to_end(&mut data)?;
59 Ok(data)
60 };
61 pub static ref START_TIME: std::time::Instant = std::time::Instant::now();
62}
63
64pub fn init() -> Receiver<()> {
66 let _ = START_TIME.elapsed();
68 fern::Dispatch::new()
70 .format(move |out, message, record| {
71 out.finish(format_args!(
72 "[{date}][{target}][{level}] {message}",
73 date = chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
74 target = record.target(),
75 level = record.level(),
76 message = message,
77 ))
78 })
79 .level(if cfg!(debug_assertions) {
80 log::LevelFilter::Debug
81 } else {
82 log::LevelFilter::Info
83 })
84 .chain(std::io::stdout())
85 .chain(fern::log_file("output.log").unwrap())
86 .apply()
87 .unwrap();
88 let (ctrlc_tx, ctrlc_rx) = mpsc::channel();
90 ctrlc::set_handler(move || {
91 ctrlc_tx.send(()).expect("Ctrl-C receiver disconnected");
92 })
93 .expect("Error setting Ctrl-C handler");
94 ctrlc_rx
95}
96
97pub async fn start_server() -> server::Server {
99 server::Server::new(format!("0.0.0.0:{}", CONFIG.port))
100}