/ src / main.rs
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  }