aboutsummaryrefslogtreecommitdiff
path: root/src-tauri/src/northstar/install.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src-tauri/src/northstar/install.rs')
-rw-r--r--src-tauri/src/northstar/install.rs144
1 files changed, 144 insertions, 0 deletions
diff --git a/src-tauri/src/northstar/install.rs b/src-tauri/src/northstar/install.rs
new file mode 100644
index 00000000..7de49eb5
--- /dev/null
+++ b/src-tauri/src/northstar/install.rs
@@ -0,0 +1,144 @@
+use anyhow::Result;
+use serde::{Deserialize, Serialize};
+use std::time::Duration;
+use std::{cell::RefCell, time::Instant};
+use ts_rs::TS;
+
+use crate::extract;
+
+#[derive(Serialize, Deserialize, Debug, Clone, TS)]
+#[ts(export)]
+enum InstallState {
+ Downloading,
+ Extracting,
+ Done,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone, TS)]
+#[ts(export)]
+struct InstallProgress {
+ current_downloaded: u64,
+ total_size: u64,
+ state: InstallState,
+}
+
+/// Copied from `papa` source code and modified
+///Install N* from the provided mod
+///
+///Checks cache, else downloads the latest version
+async fn do_install(
+ window: tauri::Window,
+ nmod: &thermite::model::ModVersion,
+ game_path: &std::path::Path,
+) -> Result<()> {
+ let filename = format!("northstar-{}.zip", nmod.version);
+ let download_directory = format!("{}/___flightcore-temp-download-dir/", game_path.display());
+
+ std::fs::create_dir_all(download_directory.clone())?;
+
+ let download_path = format!("{}/{}", download_directory, filename);
+ log::info!("Download path: {download_path}");
+
+ let last_emit = RefCell::new(Instant::now()); // Keep track of the last time a signal was emitted
+ let nfile = thermite::core::manage::download_file_with_progress(
+ &nmod.url,
+ download_path,
+ |delta, current, total| {
+ if delta != 0 {
+ // Only emit a signal once every 100ms
+ // This way we don't bombard the frontend with events on fast download speeds
+ let time_since_last_emit = Instant::now().duration_since(*last_emit.borrow());
+ if time_since_last_emit >= Duration::from_millis(100) {
+ window
+ .emit(
+ "northstar-install-download-progress",
+ InstallProgress {
+ current_downloaded: current,
+ total_size: total,
+ state: InstallState::Downloading,
+ },
+ )
+ .unwrap();
+ *last_emit.borrow_mut() = Instant::now();
+ }
+ }
+ },
+ )
+ .unwrap();
+
+ window
+ .emit(
+ "northstar-install-download-progress",
+ InstallProgress {
+ current_downloaded: 0,
+ total_size: 0,
+ state: InstallState::Extracting,
+ },
+ )
+ .unwrap();
+
+ log::info!("Extracting Northstar...");
+ extract(nfile, game_path)?;
+
+ // Delete old copy
+ log::info!("Delete temp folder again");
+ std::fs::remove_dir_all(download_directory).unwrap();
+
+ log::info!("Done installing Northstar!");
+ window
+ .emit(
+ "northstar-install-download-progress",
+ InstallProgress {
+ current_downloaded: 0,
+ total_size: 0,
+ state: InstallState::Done,
+ },
+ )
+ .unwrap();
+
+ Ok(())
+}
+
+pub async fn install_northstar(
+ window: tauri::Window,
+ game_path: &str,
+ northstar_package_name: String,
+ version_number: Option<String>,
+) -> Result<String, String> {
+ let index = thermite::api::get_package_index().unwrap().to_vec();
+ let nmod = index
+ .iter()
+ .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase())
+ .ok_or_else(|| panic!("Couldn't find Northstar on thunderstore???"))
+ .unwrap();
+
+ // Use passed version or latest if no version was passed
+ let version = version_number.as_ref().unwrap_or(&nmod.latest);
+
+ log::info!("Install path \"{}\"", game_path);
+
+ match do_install(
+ window,
+ nmod.versions.get(version).unwrap(),
+ std::path::Path::new(game_path),
+ )
+ .await
+ {
+ Ok(_) => (),
+ Err(err) => {
+ if game_path
+ .to_lowercase()
+ .contains(&r#"C:\Program Files\"#.to_lowercase())
+ // default is `C:\Program Files\EA Games\Titanfall2`
+ {
+ return Err(
+ "Cannot install to default EA App install path, please move Titanfall2 to a different install location.".to_string(),
+ );
+ } else {
+ return Err(err.to_string());
+ }
+ }
+ }
+
+ Ok(nmod.latest.clone())
+}