mod cmd; mod model; mod pkg; mod pkg_store; mod profile; mod util; mod start; mod liner; mod download_handler; mod appdata; mod display; use anyhow::anyhow; use closure::closure; use appdata::AppData; use model::misc::Game; use pkg::PkgKey; use profile::Profile; use tauri::{Listener, Manager}; use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_cli::CliExt; use tokio::{sync::Mutex, fs, try_join}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub async fn run(_args: Vec) { simple_logger::init_with_env().expect("Unable to initialize the logger"); log::info!( "Running from {}", std::env::current_dir() .unwrap_or_default() .to_str() .unwrap_or_default() ); tauri::Builder::default() .plugin(tauri_plugin_single_instance::init(|app, args, _cwd| { let _ = app .get_webview_window("main") .expect("No main window") .set_focus(); if args.len() == 2 { // Todo deindent this chimera let url = &args[1]; if &url[..13] == "rainycolor://" { log::info!("Deep link: {}", url); let regex = regex::Regex::new( r"rainycolor://v1/install/rainy\.patafour\.zip/([^/]+)/([^/]+)/[0-9]+\.[0-9]+\.[0-9]+/" ).expect("Invalid regex"); if let Some(caps) = regex.captures(url) { if caps.len() == 3 { let apph = app.clone(); let key = PkgKey(format!("{}-{}", caps.get(1).unwrap().as_str(), caps.get(2).unwrap().as_str())); tauri::async_runtime::spawn(async move { let mutex = apph.state::>(); let mut appd = mutex.lock().await; _ = appd.pkgs.fetch_listings().await; if let Err(e) = appd.pkgs.install_package(&key, true, true).await { log::warn!("Fail: {}", e.to_string()); } }); } } } } })) .plugin(tauri_plugin_cli::init()) .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_deep_link::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_opener::init()) .setup(|app| { let apph = app.handle(); util::init_dirs(&apph); let mut app_data = AppData::new(app.handle().clone()); let start_immediately; if let Ok(matches) = app.cli().matches() { let start_arg = matches.args.get("start").expect("Invalid argument configuration"); let game_arg = matches.args.get("game").expect("Invalid argument configuration"); let name_arg = matches.args.get("name").expect("Invalid argument configuration"); log::debug!("{:?} {:?} {:?}", start_arg, game_arg, name_arg); if start_arg.occurrences > 0 { start_immediately = true; app_data.remain_open = false; } else { tauri::WebviewWindowBuilder::new(app, "main", tauri::WebviewUrl::App("index.html".into())) .title("STARTLINER") .inner_size(600f64, 500f64) .min_inner_size(600f64, 500f64) .build()?; start_immediately = false; } if game_arg.occurrences == 1 && name_arg.occurrences == 1 { let game = game_arg.value.as_str().unwrap(); let name = name_arg.value.as_str().unwrap(); app_data.switch_profile( Game::from_str(game).ok_or_else(|| anyhow!("Invalid game"))?, name.to_owned() )?; } } else { return Err(anyhow!("Invalid command line arguments").into()); } app.manage(Mutex::new(app_data)); app.deep_link().register_all()?; log::debug!("\n{:?}\n{:?}\n{:?}", util::config_dir(), util::pkg_dir(), util::cache_dir()); tauri::async_runtime::spawn(async { let e = try_join!( fs::create_dir_all(util::config_dir()), fs::create_dir_all(util::pkg_dir()), fs::create_dir_all(util::cache_dir()) ); if let Err(e) = e { log::error!("Unable to create base directories: {}", e); std::process::exit(1); } }); app.listen("download-end", closure!(clone apph, |ev| { let raw = ev.payload(); let key = PkgKey(raw[1..raw.len()-1].to_owned()); let apph = apph.clone(); tauri::async_runtime::spawn(async move { let mutex = apph.state::>(); let mut appd = mutex.lock().await; _ = appd.pkgs.install_package(&key, true, false).await; }); })); app.listen("launch-end", closure!(clone apph, |_| { let apph = apph.clone(); tauri::async_runtime::spawn(async move { let mutex = apph.state::>(); let appd = mutex.lock().await; if !appd.remain_open { apph.exit(0); } }); })); if start_immediately == true { let apph_clone = apph.clone(); tauri::async_runtime::spawn(async { let apph_clone_clone = apph_clone.clone(); { let mtx = apph_clone.state::>(); let mut appd = mtx.lock().await; if let Err(e) = appd.pkgs.reload_all().await { log::error!("Unable to reload packages: {}", e); apph_clone.exit(1); } } if let Err(e) = cmd::startline(apph_clone).await { log::error!("Unable to launch: {}", e); apph_clone_clone.exit(1); } }); } Ok(()) }) .invoke_handler(tauri::generate_handler![ cmd::get_package, cmd::get_all_packages, cmd::reload_all_packages, cmd::fetch_listings, cmd::install_package, cmd::delete_package, cmd::toggle_package, cmd::list_profiles, cmd::init_profile, cmd::load_profile, cmd::get_current_profile, cmd::save_current_profile, cmd::set_cfg, cmd::startline, cmd::kill, cmd::list_displays, cmd::list_platform_capabilities, cmd::list_directories, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }