From b180f89104f18c68212bf3aebae4666cb706ba5e Mon Sep 17 00:00:00 2001 From: Cody Date: Sat, 8 Jun 2019 19:35:23 -0400 Subject: [PATCH] Enhances deserialization so settings which are missing are added with default values. --- voxygen/src/settings.rs | 177 +++++++++++++++++++++++++--------------- 1 file changed, 110 insertions(+), 67 deletions(-) diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 635cbf0d39..0e8d73cc18 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -4,21 +4,9 @@ use glutin::{MouseButton, VirtualKeyCode}; use serde_derive::{Deserialize, Serialize}; 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. #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] pub struct ControlSettings { pub toggle_cursor: KeyMouse, pub escape: KeyMouse, @@ -45,35 +33,108 @@ pub struct ControlSettings { 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. #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] pub struct GameplaySettings { pub pan_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)] +#[serde(default)] pub struct NetworkingSettings { pub username: String, pub servers: Vec, 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)] +#[serde(default)] pub struct Log { 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. #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] pub struct GraphicsSettings { pub view_distance: 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 /// device is used. #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] pub struct AudioSettings { pub music_volume: f32, pub sfx_volume: f32, @@ -82,55 +143,38 @@ pub struct AudioSettings { pub audio_device: Option, } +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 { fn default() -> Self { Settings { - controls: ControlSettings { - 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), - }, - 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, - }, + controls: ControlSettings::default(), + gameplay: GameplaySettings::default(), + networking: NetworkingSettings::default(), + log: Log::default(), + graphics: GraphicsSettings::default(), + audio: AudioSettings::default(), show_disclaimer: true, } } @@ -150,23 +194,22 @@ impl Settings { pub fn save_to_file(&self) -> std::io::Result<()> { let path = Settings::get_settings_path(); - if let Some(dir) = path.parent() { fs::create_dir_all(dir)?; } - let mut config_file = fs::File::create(path)?; + let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap(); config_file.write_all(s.as_bytes()).unwrap(); Ok(()) } fn get_settings_path() -> PathBuf { - let proj_dirs = - ProjectDirs::from("net", "veloren", "voxygen").expect("No home directory defined!"); - let path = proj_dirs.config_dir(); - path.join("settings"); - let path = path.with_extension("ron"); - path + let proj_dirs = ProjectDirs::from("net", "veloren", "voxygen") + .expect("System's $HOME directory path not found!"); + proj_dirs + .config_dir() + .join("settings") + .with_extension("ron") } }