Enhances deserialization so settings which are missing are added with default values.

This commit is contained in:
Cody 2019-06-08 19:35:23 -04:00
parent 026ac32972
commit b180f89104
No known key found for this signature in database
GPG Key ID: 4953DADF9B6AD3C8

View File

@ -4,21 +4,9 @@ use glutin::{MouseButton, VirtualKeyCode};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::{fs, io::prelude::*, path::PathBuf}; use std::{fs, io::prelude::*, path::PathBuf};
/// `Settings` contains everything that can be configured in the settings.ron file.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct Settings {
pub controls: ControlSettings,
pub gameplay: GameplaySettings,
pub networking: NetworkingSettings,
pub log: Log,
pub graphics: GraphicsSettings,
pub audio: AudioSettings,
pub show_disclaimer: bool,
}
/// `ControlSettings` contains keybindings. /// `ControlSettings` contains keybindings.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct ControlSettings { pub struct ControlSettings {
pub toggle_cursor: KeyMouse, pub toggle_cursor: KeyMouse,
pub escape: KeyMouse, pub escape: KeyMouse,
@ -45,35 +33,108 @@ pub struct ControlSettings {
pub attack: KeyMouse, pub attack: KeyMouse,
} }
impl Default for ControlSettings {
fn default() -> Self {
Self {
toggle_cursor: KeyMouse::Key(VirtualKeyCode::Tab),
escape: KeyMouse::Key(VirtualKeyCode::Escape),
enter: KeyMouse::Key(VirtualKeyCode::Return),
move_forward: KeyMouse::Key(VirtualKeyCode::W),
move_left: KeyMouse::Key(VirtualKeyCode::A),
move_back: KeyMouse::Key(VirtualKeyCode::S),
move_right: KeyMouse::Key(VirtualKeyCode::D),
jump: KeyMouse::Key(VirtualKeyCode::Space),
glide: KeyMouse::Key(VirtualKeyCode::LShift),
map: KeyMouse::Key(VirtualKeyCode::M),
bag: KeyMouse::Key(VirtualKeyCode::B),
quest_log: KeyMouse::Key(VirtualKeyCode::L),
character_window: KeyMouse::Key(VirtualKeyCode::C),
social: KeyMouse::Key(VirtualKeyCode::O),
spellbook: KeyMouse::Key(VirtualKeyCode::P),
settings: KeyMouse::Key(VirtualKeyCode::N),
help: KeyMouse::Key(VirtualKeyCode::F1),
toggle_interface: KeyMouse::Key(VirtualKeyCode::F2),
toggle_debug: KeyMouse::Key(VirtualKeyCode::F3),
fullscreen: KeyMouse::Key(VirtualKeyCode::F11),
screenshot: KeyMouse::Key(VirtualKeyCode::F4),
toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6),
attack: KeyMouse::Mouse(MouseButton::Left),
}
}
}
/// `GameplaySettings` contains sensitivity and gameplay options. /// `GameplaySettings` contains sensitivity and gameplay options.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct GameplaySettings { pub struct GameplaySettings {
pub pan_sensitivity: u32, pub pan_sensitivity: u32,
pub zoom_sensitivity: u32, pub zoom_sensitivity: u32,
} }
impl Default for GameplaySettings {
fn default() -> Self {
Self {
pan_sensitivity: 100,
zoom_sensitivity: 100,
}
}
}
/// `NetworkingSettings` stores server and networking settings.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct NetworkingSettings { pub struct NetworkingSettings {
pub username: String, pub username: String,
pub servers: Vec<String>, pub servers: Vec<String>,
pub default_server: usize, pub default_server: usize,
} }
impl Default for NetworkingSettings {
fn default() -> Self {
Self {
username: "Username".to_string(),
servers: vec!["server.veloren.net".to_string()],
default_server: 0,
}
}
}
/// `Log` stores the name to the log file.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct Log { pub struct Log {
pub file: PathBuf, pub file: PathBuf,
} }
impl Default for Log {
fn default() -> Self {
Self {
file: "voxygen.log".into(),
}
}
}
/// `GraphicsSettings` contains settings related to framerate and in-game visuals. /// `GraphicsSettings` contains settings related to framerate and in-game visuals.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct GraphicsSettings { pub struct GraphicsSettings {
pub view_distance: u32, pub view_distance: u32,
pub max_fps: u32, pub max_fps: u32,
} }
impl Default for GraphicsSettings {
fn default() -> Self {
Self {
view_distance: 5,
max_fps: 60,
}
}
}
/// `AudioSettings` controls the volume of different audio subsystems and which /// `AudioSettings` controls the volume of different audio subsystems and which
/// device is used. /// device is used.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct AudioSettings { pub struct AudioSettings {
pub music_volume: f32, pub music_volume: f32,
pub sfx_volume: f32, pub sfx_volume: f32,
@ -82,55 +143,38 @@ pub struct AudioSettings {
pub audio_device: Option<String>, pub audio_device: Option<String>,
} }
impl Default for AudioSettings {
fn default() -> Self {
Self {
music_volume: 0.5,
sfx_volume: 0.5,
audio_device: None,
}
}
}
/// `Settings` contains everything that can be configured in the settings.ron file.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct Settings {
pub controls: ControlSettings,
pub gameplay: GameplaySettings,
pub networking: NetworkingSettings,
pub log: Log,
pub graphics: GraphicsSettings,
pub audio: AudioSettings,
pub show_disclaimer: bool,
}
impl Default for Settings { impl Default for Settings {
fn default() -> Self { fn default() -> Self {
Settings { Settings {
controls: ControlSettings { controls: ControlSettings::default(),
toggle_cursor: KeyMouse::Key(VirtualKeyCode::Tab), gameplay: GameplaySettings::default(),
escape: KeyMouse::Key(VirtualKeyCode::Escape), networking: NetworkingSettings::default(),
enter: KeyMouse::Key(VirtualKeyCode::Return), log: Log::default(),
move_forward: KeyMouse::Key(VirtualKeyCode::W), graphics: GraphicsSettings::default(),
move_left: KeyMouse::Key(VirtualKeyCode::A), audio: AudioSettings::default(),
move_back: KeyMouse::Key(VirtualKeyCode::S),
move_right: KeyMouse::Key(VirtualKeyCode::D),
jump: KeyMouse::Key(VirtualKeyCode::Space),
glide: KeyMouse::Key(VirtualKeyCode::LShift),
map: KeyMouse::Key(VirtualKeyCode::M),
bag: KeyMouse::Key(VirtualKeyCode::B),
quest_log: KeyMouse::Key(VirtualKeyCode::L),
character_window: KeyMouse::Key(VirtualKeyCode::C),
social: KeyMouse::Key(VirtualKeyCode::O),
spellbook: KeyMouse::Key(VirtualKeyCode::P),
settings: KeyMouse::Key(VirtualKeyCode::N),
help: KeyMouse::Key(VirtualKeyCode::F1),
toggle_interface: KeyMouse::Key(VirtualKeyCode::F2),
toggle_debug: KeyMouse::Key(VirtualKeyCode::F3),
fullscreen: KeyMouse::Key(VirtualKeyCode::F11),
screenshot: KeyMouse::Key(VirtualKeyCode::F4),
toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6),
attack: KeyMouse::Mouse(MouseButton::Left),
},
gameplay: GameplaySettings {
pan_sensitivity: 100,
zoom_sensitivity: 100,
},
networking: NetworkingSettings {
username: "Username".to_string(),
servers: vec!["server.veloren.net".to_string()],
default_server: 0,
},
log: Log {
file: "voxygen.log".into(),
},
graphics: GraphicsSettings {
view_distance: 5,
max_fps: 60,
},
audio: AudioSettings {
music_volume: 0.5,
sfx_volume: 0.5,
audio_device: None,
},
show_disclaimer: true, show_disclaimer: true,
} }
} }
@ -150,23 +194,22 @@ impl Settings {
pub fn save_to_file(&self) -> std::io::Result<()> { pub fn save_to_file(&self) -> std::io::Result<()> {
let path = Settings::get_settings_path(); let path = Settings::get_settings_path();
if let Some(dir) = path.parent() { if let Some(dir) = path.parent() {
fs::create_dir_all(dir)?; fs::create_dir_all(dir)?;
} }
let mut config_file = fs::File::create(path)?; let mut config_file = fs::File::create(path)?;
let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap(); let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap();
config_file.write_all(s.as_bytes()).unwrap(); config_file.write_all(s.as_bytes()).unwrap();
Ok(()) Ok(())
} }
fn get_settings_path() -> PathBuf { fn get_settings_path() -> PathBuf {
let proj_dirs = let proj_dirs = ProjectDirs::from("net", "veloren", "voxygen")
ProjectDirs::from("net", "veloren", "voxygen").expect("No home directory defined!"); .expect("System's $HOME directory path not found!");
let path = proj_dirs.config_dir(); proj_dirs
path.join("settings"); .config_dir()
let path = path.with_extension("ron"); .join("settings")
path .with_extension("ron")
} }
} }