2020-10-05 08:35:24 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-10-15 18:17:45 +00:00
|
|
|
use std::{
|
|
|
|
fs,
|
|
|
|
net::{Ipv4Addr, SocketAddr},
|
|
|
|
path::PathBuf,
|
|
|
|
};
|
2020-10-05 08:35:24 +00:00
|
|
|
use tracing::warn;
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
#[serde(default)]
|
|
|
|
pub struct Settings {
|
|
|
|
pub update_shutdown_grace_period_secs: u32,
|
|
|
|
pub update_shutdown_message: String,
|
2023-10-15 18:17:45 +00:00
|
|
|
pub web_address: SocketAddr,
|
|
|
|
/// SECRET API HEADER used to access the chat api, if disabled the API is
|
|
|
|
/// unreachable
|
|
|
|
pub web_chat_secret: Option<String>,
|
2020-10-05 08:35:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Settings {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
update_shutdown_grace_period_secs: 120,
|
|
|
|
update_shutdown_message: "The server is restarting for an update".to_owned(),
|
2023-10-15 18:17:45 +00:00
|
|
|
web_address: SocketAddr::from((Ipv4Addr::LOCALHOST, 14005)),
|
|
|
|
web_chat_secret: None,
|
2020-10-05 08:35:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Settings {
|
|
|
|
pub fn load() -> Self {
|
|
|
|
let path = Self::get_settings_path();
|
|
|
|
|
|
|
|
if let Ok(file) = fs::File::open(&path) {
|
|
|
|
match ron::de::from_reader(file) {
|
|
|
|
Ok(s) => return s,
|
|
|
|
Err(e) => {
|
|
|
|
warn!(?e, "Failed to parse setting file! Fallback to default.");
|
|
|
|
// Rename the corrupted settings file
|
|
|
|
let mut new_path = path.to_owned();
|
|
|
|
new_path.pop();
|
|
|
|
new_path.push("settings.invalid.ron");
|
2022-07-15 12:08:04 +00:00
|
|
|
if let Err(e) = fs::rename(&path, &new_path) {
|
2020-10-05 08:35:24 +00:00
|
|
|
warn!(?e, ?path, ?new_path, "Failed to rename settings file.");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// This is reached if either:
|
|
|
|
// - The file can't be opened (presumably it doesn't exist)
|
|
|
|
// - Or there was an error parsing the file
|
|
|
|
let default_settings = Self::default();
|
|
|
|
default_settings.save_to_file_warn();
|
|
|
|
default_settings
|
|
|
|
}
|
|
|
|
|
Added non-admin moderators and timed bans.
The security model has been updated to reflect this change (for example,
moderators cannot revert a ban by an administrator). Ban history is
also now recorded in the ban file, and much more information about the
ban is stored (whitelists and administrators also have extra
information).
To support the new information without losing important information,
this commit also introduces a new migration path for editable settings
(both from legacy to the new format, and between versions). Examples
of how to do this correctly, and migrate to new versions of a settings
file, are in the settings/ subdirectory.
As part of this effort, editable settings have been revamped to
guarantee atomic saves (due to the increased amount of information in
each file), some latent bugs in networking were fixed, and server-cli
has been updated to go through StructOpt for both calls through TUI
and argv, greatly simplifying parsing logic.
2021-05-08 18:22:21 +00:00
|
|
|
fn save_to_file_warn(&self) {
|
2020-10-05 08:35:24 +00:00
|
|
|
if let Err(e) = self.save_to_file() {
|
|
|
|
warn!(?e, "Failed to save settings");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn save_to_file(&self) -> std::io::Result<()> {
|
|
|
|
let path = Self::get_settings_path();
|
|
|
|
if let Some(dir) = path.parent() {
|
|
|
|
fs::create_dir_all(dir)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let ron = ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap();
|
|
|
|
fs::write(path, ron.as_bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_settings_path() -> PathBuf {
|
|
|
|
let mut path = data_dir();
|
|
|
|
path.push("settings.ron");
|
|
|
|
path
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn data_dir() -> PathBuf {
|
2021-03-08 22:40:02 +00:00
|
|
|
let mut path = common_base::userdata_dir_workspace!();
|
2020-10-05 08:35:24 +00:00
|
|
|
path.push("server-cli");
|
|
|
|
path
|
|
|
|
}
|