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