main.rs
1 /*! 2 Local Achievements is an open source desktop application for collecting, storing, 3 and tracking your achievements across multiple platforms in one unified UI. 4 */ 5 6 //Disable the additional command prompt window when running the application on Windows 7 #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] 8 9 mod battlenet; 10 mod components; 11 mod data; 12 //mod egs; 13 mod gog; 14 mod io; 15 mod macros; 16 mod net; 17 mod constants; 18 mod retroachievements; 19 mod rpcs3; 20 mod steam; 21 mod util; 22 23 use std::path::Path; 24 use std::sync::LazyLock; 25 use freya::prelude::{LaunchConfig, WindowConfig, launch}; 26 use freya::radio::RadioStation; 27 use securestore::{KeySource, SecretsManager}; 28 use tokio::sync::Mutex; 29 use tracing::Level; 30 use tracing_appender::non_blocking::WorkerGuard; 31 use crate::components::LocalAchievementsApp; 32 use crate::constants::{AppTitle, BackgroundColor, DefaultWindowSize, 33 MinimumWindowSize}; 34 use crate::data::AppData; 35 use crate::io::{FileName_LogPrefix, Path_Logs, getConfigDir, getSecretsKeyPath, 36 getSecretsVaultPath}; 37 38 static Secrets: LazyLock<Mutex<SecretsManager>> = LazyLock::new(|| { 39 let keyPath = getSecretsKeyPath() 40 .expect("Error getting the secrets key path"); 41 42 let vaultPath = getSecretsVaultPath() 43 .expect("Error getting the secrets vault path"); 44 45 if !keyPath.exists() || !vaultPath.exists() 46 { 47 let m = SecretsManager::new(KeySource::Csprng) 48 .expect("Error creating secrets manager with new key"); 49 50 _ = m.export_key(keyPath.clone()) 51 .expect("Error exporting new secrets key"); 52 53 _ = m.save_as(vaultPath.clone()) 54 .expect("Error saving new secrets vault to file"); 55 } 56 57 Mutex::new( 58 SecretsManager::load(vaultPath, KeySource::Path(&keyPath)) 59 .expect("Error loading secrets vault from file") 60 ) 61 }); 62 63 fn main() 64 { 65 let _guard = configureLogger(); 66 67 let tokioBuilder = tokio::runtime::Builder::new_multi_thread() 68 .enable_all() 69 .build() 70 .unwrap(); 71 72 let _tokioRuntime = tokioBuilder.enter(); 73 74 let radioStation = RadioStation::create_global(AppData::default()); 75 76 launch(LaunchConfig::new() 77 .with_window( 78 WindowConfig::new_app( 79 LocalAchievementsApp::new(radioStation) 80 ) 81 .with_background(BackgroundColor) 82 .with_min_size(MinimumWindowSize.0, MinimumWindowSize.1) 83 .with_size(DefaultWindowSize.0, DefaultWindowSize.1) 84 .with_title(AppTitle) 85 .with_transparency(false) 86 ) 87 ); 88 } 89 90 fn configureLogger() -> WorkerGuard 91 { 92 let dir = getConfigDir(true).unwrap(); 93 94 let logPath = Path::new(&dir) 95 .join(Path_Logs); 96 97 let fileAppender = tracing_appender::rolling::daily(logPath, FileName_LogPrefix); 98 let (nonBlocking, workerGuard) = tracing_appender::non_blocking(fileAppender); 99 100 let format = tracing_subscriber::fmt::format() 101 .with_ansi(false) 102 .compact(); 103 104 tracing_subscriber::fmt() 105 .event_format(format) 106 .with_max_level(Level::INFO) 107 .with_writer(nonBlocking) 108 .init(); 109 110 return workerGuard; 111 }