2019-10-11 12:19:55 +00:00
|
|
|
use portpicker::pick_unused_port;
|
2019-06-29 16:41:26 +00:00
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2019-07-01 09:37:17 +00:00
|
|
|
use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf};
|
2020-01-18 18:41:37 +00:00
|
|
|
use world::sim::FileOpts;
|
|
|
|
|
|
|
|
const DEFAULT_WORLD_SEED: u32 = 5284;
|
2019-06-29 16:41:26 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
#[serde(default)]
|
|
|
|
pub struct ServerSettings {
|
2019-10-11 12:19:55 +00:00
|
|
|
pub gameserver_address: SocketAddr,
|
|
|
|
pub metrics_address: SocketAddr,
|
2019-12-21 17:02:39 +00:00
|
|
|
pub auth_server_address: Option<String>,
|
2019-07-01 11:19:26 +00:00
|
|
|
pub max_players: usize,
|
2019-06-29 16:41:26 +00:00
|
|
|
pub world_seed: u32,
|
|
|
|
//pub pvp_enabled: bool,
|
2019-07-01 09:37:17 +00:00
|
|
|
pub server_name: String,
|
|
|
|
pub server_description: String,
|
2019-07-12 13:03:35 +00:00
|
|
|
pub start_time: f64,
|
2019-08-12 14:05:58 +00:00
|
|
|
pub admins: Vec<String>,
|
2020-02-01 20:39:39 +00:00
|
|
|
/// When set to None, loads the default map file (if available); otherwise,
|
|
|
|
/// uses the value of the file options to decide how to proceed.
|
2020-01-18 18:41:37 +00:00
|
|
|
pub map_file: Option<FileOpts>,
|
2020-05-12 23:58:15 +00:00
|
|
|
pub persistence_db_dir: String,
|
2019-06-29 16:41:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ServerSettings {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
2019-10-11 12:19:55 +00:00
|
|
|
gameserver_address: SocketAddr::from(([0; 4], 14004)),
|
|
|
|
metrics_address: SocketAddr::from(([0; 4], 14005)),
|
2019-12-21 17:02:39 +00:00
|
|
|
auth_server_address: Some("https://auth.veloren.net".into()),
|
2020-01-18 18:41:37 +00:00
|
|
|
world_seed: DEFAULT_WORLD_SEED,
|
2019-07-28 09:21:17 +00:00
|
|
|
server_name: "Veloren Alpha".to_owned(),
|
2019-07-01 09:37:17 +00:00
|
|
|
server_description: "This is the best Veloren server.".to_owned(),
|
2019-07-28 09:21:17 +00:00
|
|
|
max_players: 100,
|
2019-07-28 10:46:03 +00:00
|
|
|
start_time: 9.0 * 3600.0,
|
2019-12-11 09:14:50 +00:00
|
|
|
map_file: None,
|
2019-10-23 16:38:09 +00:00
|
|
|
admins: [
|
|
|
|
"Pfau",
|
|
|
|
"zesterer",
|
|
|
|
"xMAC94x",
|
|
|
|
"Timo",
|
|
|
|
"Songtronix",
|
|
|
|
"Slipped",
|
|
|
|
"Sharp",
|
|
|
|
"Acrimon",
|
|
|
|
"imbris",
|
|
|
|
"YuriMomo",
|
|
|
|
"Vechro",
|
|
|
|
"AngelOnFira",
|
|
|
|
"Nancok",
|
|
|
|
"Qutrin",
|
|
|
|
"Mckol",
|
2020-01-30 18:01:24 +00:00
|
|
|
"Treeco",
|
2019-10-23 18:23:31 +00:00
|
|
|
]
|
|
|
|
.iter()
|
|
|
|
.map(|n| n.to_string())
|
|
|
|
.collect(),
|
2020-05-12 23:58:15 +00:00
|
|
|
persistence_db_dir: "saves".to_owned(),
|
2019-06-29 16:41:26 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-01 09:37:17 +00:00
|
|
|
}
|
2019-06-29 16:41:26 +00:00
|
|
|
|
|
|
|
impl ServerSettings {
|
|
|
|
pub fn load() -> Self {
|
|
|
|
let path = ServerSettings::get_settings_path();
|
|
|
|
|
|
|
|
if let Ok(file) = fs::File::open(path) {
|
2019-07-04 17:37:56 +00:00
|
|
|
match ron::de::from_reader(file) {
|
|
|
|
Ok(x) => x,
|
|
|
|
Err(e) => {
|
|
|
|
log::warn!("Failed to parse setting file! Fallback to default. {}", e);
|
|
|
|
Self::default()
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
2019-07-04 17:37:56 +00:00
|
|
|
}
|
2019-06-29 16:41:26 +00:00
|
|
|
} else {
|
2019-07-04 17:37:56 +00:00
|
|
|
let default_settings = Self::default();
|
|
|
|
|
|
|
|
match default_settings.save_to_file() {
|
|
|
|
Err(e) => log::error!("Failed to create default setting file! {}", e),
|
2020-02-01 20:39:39 +00:00
|
|
|
_ => {},
|
2019-07-04 17:37:56 +00:00
|
|
|
}
|
|
|
|
default_settings
|
2019-06-29 16:41:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn save_to_file(&self) -> std::io::Result<()> {
|
|
|
|
let path = ServerSettings::get_settings_path();
|
|
|
|
let mut config_file = fs::File::create(path)?;
|
|
|
|
|
2019-10-23 18:23:31 +00:00
|
|
|
let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default())
|
|
|
|
.expect("Failed serialize settings.");
|
|
|
|
config_file
|
|
|
|
.write_all(s.as_bytes())
|
|
|
|
.expect("Failed to write to config file.");
|
2019-06-29 16:41:26 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-05-13 23:37:53 +00:00
|
|
|
pub fn singleplayer(persistence_db_dir: String) -> Self {
|
2020-01-24 02:45:29 +00:00
|
|
|
let load = Self::load();
|
2019-08-14 15:51:59 +00:00
|
|
|
Self {
|
2020-02-01 20:39:39 +00:00
|
|
|
//BUG: theoretically another process can grab the port between here and server
|
|
|
|
// creation, however the timewindow is quite small
|
2019-10-11 12:19:55 +00:00
|
|
|
gameserver_address: SocketAddr::from((
|
|
|
|
[127, 0, 0, 1],
|
|
|
|
pick_unused_port().expect("Failed to find unused port!"),
|
|
|
|
)),
|
|
|
|
metrics_address: SocketAddr::from((
|
|
|
|
[127, 0, 0, 1],
|
|
|
|
pick_unused_port().expect("Failed to find unused port!"),
|
|
|
|
)),
|
2019-12-21 17:02:39 +00:00
|
|
|
auth_server_address: None,
|
2020-01-24 02:45:29 +00:00
|
|
|
// If loading the default map file, make sure the seed is also default.
|
|
|
|
world_seed: if load.map_file.is_some() {
|
|
|
|
load.world_seed
|
|
|
|
} else {
|
|
|
|
DEFAULT_WORLD_SEED
|
|
|
|
},
|
2019-08-14 15:51:59 +00:00
|
|
|
server_name: "Singleplayer".to_owned(),
|
2019-08-18 18:07:21 +00:00
|
|
|
server_description: "Who needs friends anyway?".to_owned(),
|
2019-08-14 15:51:59 +00:00
|
|
|
max_players: 100,
|
|
|
|
start_time: 9.0 * 3600.0,
|
2020-02-01 20:39:39 +00:00
|
|
|
admins: vec!["singleplayer".to_string()], /* TODO: Let the player choose if they want
|
|
|
|
* to use admin commands or not */
|
2020-05-13 23:37:53 +00:00
|
|
|
persistence_db_dir,
|
2020-04-15 11:31:16 +00:00
|
|
|
..load // Fill in remaining fields from server_settings.ron.
|
2019-08-14 15:51:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-15 11:31:16 +00:00
|
|
|
fn get_settings_path() -> PathBuf { PathBuf::from(r"server_settings.ron") }
|
2019-07-01 09:37:17 +00:00
|
|
|
}
|
2020-05-12 23:58:15 +00:00
|
|
|
|
|
|
|
pub struct PersistenceDBDir(pub String);
|