diff options
Diffstat (limited to 'src-tauri/src')
-rw-r--r-- | src-tauri/src/constants.rs | 4 | ||||
-rw-r--r-- | src-tauri/src/github/mod.rs | 2 | ||||
-rw-r--r-- | src-tauri/src/github/pull_requests.rs | 2 | ||||
-rw-r--r-- | src-tauri/src/main.rs | 384 | ||||
-rw-r--r-- | src-tauri/src/mod_management/mod.rs | 24 | ||||
-rw-r--r-- | src-tauri/src/northstar/install.rs | 43 | ||||
-rw-r--r-- | src-tauri/src/northstar/mod.rs | 106 | ||||
-rw-r--r-- | src-tauri/src/northstar/profile.rs | 17 | ||||
-rw-r--r-- | src-tauri/src/platform_specific/linux.rs | 21 | ||||
-rw-r--r-- | src-tauri/src/platform_specific/mod.rs | 52 | ||||
-rw-r--r-- | src-tauri/src/platform_specific/windows.rs | 2 | ||||
-rw-r--r-- | src-tauri/src/repair_and_verify/mod.rs | 37 | ||||
-rw-r--r-- | src-tauri/src/util.rs | 52 |
13 files changed, 371 insertions, 375 deletions
diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 33aefac8..7ee98f95 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -58,7 +58,3 @@ pub const NORTHSTAR_DLL: &str = "Northstar.dll"; /// Profile that Northstar defaults to and ships with pub const NORTHSTAR_DEFAULT_PROFILE: &str = "R2Northstar"; - -/// List of valid compatibility tools that Northstar can be launched with -pub const VALID_NORTHSTAR_PROTON_BUILDS: [&str; 3] = - ["NorthstarProton-8.1-1", "GE-Proton8-13", "GE-Proton8-11"]; diff --git a/src-tauri/src/github/mod.rs b/src-tauri/src/github/mod.rs index f35b64a1..0174084f 100644 --- a/src-tauri/src/github/mod.rs +++ b/src-tauri/src/github/mod.rs @@ -160,7 +160,7 @@ fn generate_flightcore_release_notes(commits: Vec<String>) -> String { "feat" => "**Features:**", "fix" => "**Bug Fixes:**", "docs" => "**Documentation:**", - "style" => "**Styles:**", + "style" => "**Code style changes:**", "refactor" => "**Code Refactoring:**", "build" => "**Build:**", "test" => "**Tests:**", diff --git a/src-tauri/src/github/pull_requests.rs b/src-tauri/src/github/pull_requests.rs index ccb45dff..91d8a5da 100644 --- a/src-tauri/src/github/pull_requests.rs +++ b/src-tauri/src/github/pull_requests.rs @@ -1,7 +1,7 @@ use crate::github::release_notes::fetch_github_releases_api; -use crate::check_is_valid_game_path; use crate::constants::{APP_USER_AGENT, PULLS_API_ENDPOINT_LAUNCHER, PULLS_API_ENDPOINT_MODS}; +use crate::repair_and_verify::check_is_valid_game_path; use crate::GameInstall; use anyhow::anyhow; use serde::{Deserialize, Serialize}; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 66bb98d2..09242680 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -9,23 +9,22 @@ use std::{ time::Duration, }; -use crate::constants::REFRESH_DELAY; - +mod constants; mod development; mod github; mod mod_management; mod northstar; +mod platform_specific; mod repair_and_verify; mod thunderstore; mod util; -use semver::Version; use serde::{Deserialize, Serialize}; #[cfg(target_os = "windows")] use tauri::api::dialog::blocking::MessageDialogBuilder; #[cfg(target_os = "windows")] use tauri::api::dialog::{MessageDialogButtons, MessageDialogKind}; -use tauri::{Manager, Runtime}; +use tauri::Manager; use tokio::time::sleep; use ts_rs::TS; @@ -38,7 +37,7 @@ struct NorthstarThunderstoreRelease { #[derive(Serialize, Deserialize, Debug, Clone, TS)] #[ts(export)] -struct NorthstarThunderstoreReleaseWrapper { +pub struct NorthstarThunderstoreReleaseWrapper { label: String, value: NorthstarThunderstoreRelease, } @@ -103,7 +102,7 @@ fn main() { let app_handle = app.app_handle(); tauri::async_runtime::spawn(async move { loop { - sleep(REFRESH_DELAY).await; + sleep(constants::REFRESH_DELAY).await; app_handle .emit_all( "northstar-statistics", @@ -119,13 +118,13 @@ fn main() { .invoke_handler(tauri::generate_handler![ util::force_panic, northstar::install::find_game_install_location, - get_flightcore_version_number, + util::get_flightcore_version_number, northstar::get_northstar_version_number, - check_is_northstar_outdated, - verify_install_location, - get_host_os, - install_northstar_caller, - update_northstar, + northstar::check_is_northstar_outdated, + repair_and_verify::verify_install_location, + platform_specific::get_host_os, + northstar::install::install_northstar_wrapper, + northstar::install::update_northstar, northstar::launch_northstar, northstar::launch_northstar_steam, github::release_notes::check_is_flightcore_outdated, @@ -135,19 +134,19 @@ fn main() { repair_and_verify::disable_all_but_core, util::is_debug_mode, github::release_notes::get_northstar_release_notes, - linux_checks, + platform_specific::linux_checks, mod_management::get_installed_mods_and_properties, - install_mod_caller, - clean_up_download_folder_caller, + mod_management::install_mod_wrapper, + repair_and_verify::clean_up_download_folder_wrapper, github::release_notes::get_newest_flightcore_version, mod_management::delete_northstar_mod, util::get_server_player_count, util::kill_northstar, mod_management::delete_thunderstore_mod, - install_northstar_proton_wrapper, - uninstall_northstar_proton_wrapper, - get_local_northstar_proton_wrapper_version, - open_repair_window, + platform_specific::install_northstar_proton_wrapper, + platform_specific::uninstall_northstar_proton_wrapper, + platform_specific::get_local_northstar_proton_wrapper_version, + util::open_repair_window, thunderstore::query_thunderstore_packages_api, github::get_list_of_tags, github::compare_tags, @@ -155,11 +154,12 @@ fn main() { github::pull_requests::apply_launcher_pr, github::pull_requests::apply_mods_pr, github::pull_requests::get_launcher_download_link, - close_application, + util::close_application, development::install_git_main, - get_available_northstar_versions, + northstar::get_available_northstar_versions, northstar::profile::fetch_profiles, northstar::profile::validate_profile, + northstar::profile::delete_profile, ]) .run(tauri::generate_context!()) { @@ -193,272 +193,7 @@ fn main() { }; } -/// Returns true if linux compatible -#[tauri::command] -async fn linux_checks() -> Result<(), String> { - // Different behaviour depending on OS - // MacOS is missing as it is not a target - // in turn this means this application will not build on MacOS. - #[cfg(target_os = "windows")] - { - Err("Not available on Windows".to_string()) - } - - #[cfg(target_os = "linux")] - { - linux_checks_librs() - } -} - -/// Returns the current version number as a string -#[tauri::command] -async fn get_flightcore_version_number() -> String { - let version = env!("CARGO_PKG_VERSION"); - if cfg!(debug_assertions) { - // Debugging enabled - format!("v{} (debug mode)", version) - } else { - // Debugging disabled - format!("v{}", version) - } -} - -/// Helps with converting release candidate numbers which are different on Thunderstore -/// due to restrictions imposed by the platform -pub fn convert_release_candidate_number(version_number: String) -> String { - // This simply converts `-rc` to `0` - // Works as intended for RCs < 10, e.g. `v1.9.2-rc1` -> `v1.9.201` - // Doesn't work for larger numbers, e.g. `v1.9.2-rc11` -> `v1.9.2011` (should be `v1.9.211`) - version_number.replace("-rc", "0").replace("00", "") -} - -/// Checks if installed Northstar version is up-to-date -/// false -> Northstar install is up-to-date -/// true -> Northstar install is outdated -#[tauri::command] -async fn check_is_northstar_outdated( - game_install: GameInstall, - northstar_package_name: Option<String>, -) -> Result<bool, String> { - let northstar_package_name = match northstar_package_name { - Some(northstar_package_name) => { - if northstar_package_name.len() <= 1 { - "Northstar".to_string() - } else { - northstar_package_name - } - } - None => "Northstar".to_string(), - }; - - let index = match thermite::api::get_package_index() { - Ok(res) => res.to_vec(), - Err(err) => return Err(format!("Couldn't check if Northstar up-to-date: {err}")), - }; - let nmod = index - .iter() - .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase()) - .expect("Couldn't find Northstar on thunderstore???"); - // .ok_or_else(|| anyhow!("Couldn't find Northstar on thunderstore???"))?; - - let version_number = match northstar::get_northstar_version_number(game_install) { - Ok(version_number) => version_number, - Err(err) => { - log::warn!("{}", err); - // If we fail to get new version just assume we are up-to-date - return Err(err); - } - }; - - // Release candidate version numbers are different between `mods.json` and Thunderstore - let version_number = convert_release_candidate_number(version_number); - - if version_number != nmod.latest { - log::info!("Installed Northstar version outdated"); - Ok(true) - } else { - log::info!("Installed Northstar version up-to-date"); - Ok(false) - } -} - -/// Checks if is valid Titanfall2 install based on certain conditions -#[tauri::command] -async fn verify_install_location(game_path: String) -> bool { - match check_is_valid_game_path(&game_path) { - Ok(()) => true, - Err(err) => { - log::warn!("{}", err); - false - } - } -} - -/// Installs Northstar to the given path -#[tauri::command] -async fn install_northstar_caller( - window: tauri::Window, - game_install: GameInstall, - northstar_package_name: Option<String>, - version_number: Option<String>, -) -> Result<bool, String> { - log::info!("Running Northstar install"); - - // Get Northstar package name (`Northstar` vs `NorthstarReleaseCandidate`) - let northstar_package_name = northstar_package_name - .map(|name| { - if name.len() <= 1 { - "Northstar".to_string() - } else { - name - } - }) - .unwrap_or("Northstar".to_string()); - - match northstar::install::install_northstar( - window, - game_install, - northstar_package_name, - version_number, - ) - .await - { - Ok(_) => Ok(true), - Err(err) => { - log::error!("{}", err); - Err(err) - } - } -} - -/// Update Northstar install in the given path -#[tauri::command] -async fn update_northstar( - window: tauri::Window, - game_install: GameInstall, - northstar_package_name: Option<String>, -) -> Result<bool, String> { - log::info!("Updating Northstar"); - - // Simply re-run install with up-to-date version for upate - install_northstar_caller(window, game_install, northstar_package_name, None).await -} - -/// Installs the specified mod -#[tauri::command] -async fn install_mod_caller( - game_install: GameInstall, - thunderstore_mod_string: String, -) -> Result<(), String> { - match mod_management::fc_download_mod_and_install(&game_install, &thunderstore_mod_string).await - { - Ok(()) => (), - Err(err) => { - log::warn!("{err}"); - return Err(err); - } - }; - match repair_and_verify::clean_up_download_folder(&game_install, false) { - Ok(()) => Ok(()), - Err(err) => { - log::info!("Failed to delete download folder due to {}", err); - // Failure to delete download folder is not an error in mod install - // As such ignore. User can still force delete if need be - Ok(()) - } - } -} - -/// Installs the specified mod -#[tauri::command] -async fn clean_up_download_folder_caller( - game_install: GameInstall, - force: bool, -) -> Result<(), String> { - match repair_and_verify::clean_up_download_folder(&game_install, force) { - Ok(()) => Ok(()), - Err(err) => Err(err.to_string()), - } -} - -/// Spawns repair window -#[tauri::command] -async fn open_repair_window(handle: tauri::AppHandle) -> Result<(), String> { - // Spawn new window - let repair_window = match tauri::WindowBuilder::new( - &handle, - "RepairWindow", - tauri::WindowUrl::App("/#/repair".into()), - ) - .build() - { - Ok(res) => res, - Err(err) => return Err(err.to_string()), - }; - - // Set window title - match repair_window.set_title("FlightCore Repair Window") { - Ok(()) => (), - Err(err) => return Err(err.to_string()), - }; - Ok(()) -} - -/// Closes all windows and exits application -#[tauri::command] -async fn close_application<R: Runtime>(app: tauri::AppHandle<R>) -> Result<(), String> { - app.exit(0); // Close application - Ok(()) -} - -/// Gets list of available Northstar versions from Thunderstore -#[tauri::command] -async fn get_available_northstar_versions() -> Result<Vec<NorthstarThunderstoreReleaseWrapper>, ()> -{ - let northstar_package_name = "Northstar"; - let index = thermite::api::get_package_index().unwrap().to_vec(); - let nsmod = index - .iter() - .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase()) - .ok_or_else(|| panic!("Couldn't find Northstar on thunderstore???")) - .unwrap(); - - let mut releases: Vec<NorthstarThunderstoreReleaseWrapper> = vec![]; - for (_version_string, nsmod_version_obj) in nsmod.versions.iter() { - let current_elem = NorthstarThunderstoreRelease { - package: nsmod_version_obj.name.clone(), - version: nsmod_version_obj.version.clone(), - }; - let current_elem_wrapped = NorthstarThunderstoreReleaseWrapper { - label: format!( - "{} v{}", - nsmod_version_obj.name.clone(), - nsmod_version_obj.version.clone() - ), - value: current_elem, - }; - - releases.push(current_elem_wrapped); - } - - releases.sort_by(|a, b| { - // Parse version number - let a_ver = Version::parse(&a.value.version).unwrap(); - let b_ver = Version::parse(&b.value.version).unwrap(); - b_ver.partial_cmp(&a_ver).unwrap() // Sort newest first - }); - - Ok(releases) -} - -use anyhow::Result; - -pub mod constants; -mod platform_specific; - -#[cfg(target_os = "linux")] -use platform_specific::linux; - +/// Defines how Titanfall2 was installed (Steam, Origin, ...) #[derive(Serialize, Deserialize, Debug, Clone, TS)] #[ts(export)] pub enum InstallType { @@ -468,6 +203,10 @@ pub enum InstallType { UNKNOWN, } +/// Object holding information of the Titanfall2 install, including +/// - Install path +/// - Active profile +/// - Type of installation (Steam, Origin, ...) #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GameInstall { pub game_path: String, @@ -475,6 +214,7 @@ pub struct GameInstall { pub install_type: InstallType, } +/// Object holding various information about a Northstar mod #[derive(Serialize, Deserialize, Debug, Clone, TS)] #[ts(export)] pub struct NorthstarMod { @@ -484,73 +224,3 @@ pub struct NorthstarMod { pub enabled: bool, pub directory: String, } - -// I intend to add more linux related stuff to check here, so making a func -// for now tho it only checks `ldd --version` -// - salmon -#[cfg(target_os = "linux")] -pub fn linux_checks_librs() -> Result<(), String> { - // Perform various checks in terms of Linux compatibility - // Return early with error message if a check fails - - // check `ldd --version` to see if glibc is up to date for northstar proton - let min_required_ldd_version = 2.33; - let lddv = linux::check_glibc_v(); - if lddv < min_required_ldd_version { - return Err(format!( - "GLIBC is not version {} or greater", - min_required_ldd_version - )); - }; - - // All checks passed - Ok(()) -} - -/// Checks whether the provided path is a valid Titanfall2 gamepath by checking against a certain set of criteria -pub fn check_is_valid_game_path(game_install_path: &str) -> Result<(), String> { - let path_to_titanfall2_exe = format!("{game_install_path}/Titanfall2.exe"); - let is_correct_game_path = std::path::Path::new(&path_to_titanfall2_exe).exists(); - log::info!("Titanfall2.exe exists in path? {}", is_correct_game_path); - - // Exit early if wrong game path - if !is_correct_game_path { - return Err(format!("Incorrect game path \"{game_install_path}\"")); // Return error cause wrong game path - } - Ok(()) -} - -/// Returns identifier of host OS FlightCore is running on -#[tauri::command] -fn get_host_os() -> String { - env::consts::OS.to_string() -} - -/// On Linux attempts to install NorthstarProton -/// On Windows simply returns an error message -#[tauri::command] -async fn install_northstar_proton_wrapper() -> Result<(), String> { - #[cfg(target_os = "linux")] - return linux::install_ns_proton().map_err(|err| err.to_string()); - - #[cfg(target_os = "windows")] - Err("Not supported on Windows".to_string()) -} - -#[tauri::command] -async fn uninstall_northstar_proton_wrapper() -> Result<(), String> { - #[cfg(target_os = "linux")] - return linux::uninstall_ns_proton(); - - #[cfg(target_os = "windows")] - Err("Not supported on Windows".to_string()) -} - -#[tauri::command] -async fn get_local_northstar_proton_wrapper_version() -> Result<String, String> { - #[cfg(target_os = "linux")] - return linux::get_local_ns_proton_version(); - - #[cfg(target_os = "windows")] - Err("Not supported on Windows".to_string()) -} diff --git a/src-tauri/src/mod_management/mod.rs b/src-tauri/src/mod_management/mod.rs index a9826522..ab639b11 100644 --- a/src-tauri/src/mod_management/mod.rs +++ b/src-tauri/src/mod_management/mod.rs @@ -89,6 +89,30 @@ impl std::ops::Deref for TempFile { } } +/// Installs the specified mod +#[tauri::command] +pub async fn install_mod_wrapper( + game_install: GameInstall, + thunderstore_mod_string: String, +) -> Result<(), String> { + match fc_download_mod_and_install(&game_install, &thunderstore_mod_string).await { + Ok(()) => (), + Err(err) => { + log::warn!("{err}"); + return Err(err); + } + }; + match crate::repair_and_verify::clean_up_download_folder(&game_install, false) { + Ok(()) => Ok(()), + Err(err) => { + log::info!("Failed to delete download folder due to {}", err); + // Failure to delete download folder is not an error in mod install + // As such ignore. User can still force delete if need be + Ok(()) + } + } +} + /// Returns a serde json object of the parsed `enabledmods.json` file pub fn get_enabled_mods(game_install: &GameInstall) -> Result<serde_json::value::Value, String> { let enabledmods_json_path = format!( diff --git a/src-tauri/src/northstar/install.rs b/src-tauri/src/northstar/install.rs index 757f6c68..693d7af2 100644 --- a/src-tauri/src/northstar/install.rs +++ b/src-tauri/src/northstar/install.rs @@ -29,6 +29,49 @@ struct InstallProgress { state: InstallState, } +/// Installs Northstar to the given path +#[tauri::command] +pub async fn install_northstar_wrapper( + window: tauri::Window, + game_install: GameInstall, + northstar_package_name: Option<String>, + version_number: Option<String>, +) -> Result<bool, String> { + log::info!("Running Northstar install"); + + // Get Northstar package name (`Northstar` vs `NorthstarReleaseCandidate`) + let northstar_package_name = northstar_package_name + .map(|name| { + if name.len() <= 1 { + "Northstar".to_string() + } else { + name + } + }) + .unwrap_or("Northstar".to_string()); + + match install_northstar(window, game_install, northstar_package_name, version_number).await { + Ok(_) => Ok(true), + Err(err) => { + log::error!("{}", err); + Err(err) + } + } +} + +/// Update Northstar install in the given path +#[tauri::command] +pub async fn update_northstar( + window: tauri::Window, + game_install: GameInstall, + northstar_package_name: Option<String>, +) -> Result<bool, String> { + log::info!("Updating Northstar"); + + // Simply re-run install with up-to-date version for upate + install_northstar_wrapper(window, game_install, northstar_package_name, None).await +} + /// Copied from `papa` source code and modified ///Install N* from the provided mod /// diff --git a/src-tauri/src/northstar/mod.rs b/src-tauri/src/northstar/mod.rs index 4ee9ba82..d6f6d712 100644 --- a/src-tauri/src/northstar/mod.rs +++ b/src-tauri/src/northstar/mod.rs @@ -5,11 +5,103 @@ pub mod profile; use crate::util::check_ea_app_or_origin_running; use crate::{ - constants::{CORE_MODS, TITANFALL2_STEAM_ID, VALID_NORTHSTAR_PROTON_BUILDS}, - get_host_os, GameInstall, InstallType, + constants::{CORE_MODS, TITANFALL2_STEAM_ID}, + platform_specific::get_host_os, + GameInstall, InstallType, }; +use crate::{NorthstarThunderstoreRelease, NorthstarThunderstoreReleaseWrapper}; use anyhow::anyhow; +/// Gets list of available Northstar versions from Thunderstore +#[tauri::command] +pub async fn get_available_northstar_versions( +) -> Result<Vec<NorthstarThunderstoreReleaseWrapper>, ()> { + let northstar_package_name = "Northstar"; + let index = thermite::api::get_package_index().unwrap().to_vec(); + let nsmod = index + .iter() + .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase()) + .ok_or_else(|| panic!("Couldn't find Northstar on thunderstore???")) + .unwrap(); + + let mut releases: Vec<NorthstarThunderstoreReleaseWrapper> = vec![]; + for (_version_string, nsmod_version_obj) in nsmod.versions.iter() { + let current_elem = NorthstarThunderstoreRelease { + package: nsmod_version_obj.name.clone(), + version: nsmod_version_obj.version.clone(), + }; + let current_elem_wrapped = NorthstarThunderstoreReleaseWrapper { + label: format!( + "{} v{}", + nsmod_version_obj.name.clone(), + nsmod_version_obj.version.clone() + ), + value: current_elem, + }; + + releases.push(current_elem_wrapped); + } + + releases.sort_by(|a, b| { + // Parse version number + let a_ver = semver::Version::parse(&a.value.version).unwrap(); + let b_ver = semver::Version::parse(&b.value.version).unwrap(); + b_ver.partial_cmp(&a_ver).unwrap() // Sort newest first + }); + + Ok(releases) +} + +/// Checks if installed Northstar version is up-to-date +/// false -> Northstar install is up-to-date +/// true -> Northstar install is outdated +#[tauri::command] +pub async fn check_is_northstar_outdated( + game_install: GameInstall, + northstar_package_name: Option<String>, +) -> Result<bool, String> { + let northstar_package_name = match northstar_package_name { + Some(northstar_package_name) => { + if northstar_package_name.len() <= 1 { + "Northstar".to_string() + } else { + northstar_package_name + } + } + None => "Northstar".to_string(), + }; + + let index = match thermite::api::get_package_index() { + Ok(res) => res.to_vec(), + Err(err) => return Err(format!("Couldn't check if Northstar up-to-date: {err}")), + }; + let nmod = index + .iter() + .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase()) + .expect("Couldn't find Northstar on thunderstore???"); + // .ok_or_else(|| anyhow!("Couldn't find Northstar on thunderstore???"))?; + + let version_number = match get_northstar_version_number(game_install) { + Ok(version_number) => version_number, + Err(err) => { + log::warn!("{}", err); + // If we fail to get new version just assume we are up-to-date + return Err(err); + } + }; + + // Release candidate version numbers are different between `mods.json` and Thunderstore + let version_number = crate::util::convert_release_candidate_number(version_number); + + if version_number != nmod.latest { + log::info!("Installed Northstar version outdated"); + Ok(true) + } else { + log::info!("Installed Northstar version up-to-date"); + Ok(false) + } +} + /// Check version number of a mod pub fn check_mod_version_number(path_to_mod_folder: &str) -> Result<String, anyhow::Error> { let data = std::fs::read_to_string(format!("{path_to_mod_folder}/mod.json"))?; @@ -158,15 +250,7 @@ pub fn launch_northstar_steam( if get_host_os() != "windows" { let titanfall2_steamid: u32 = TITANFALL2_STEAM_ID.parse().unwrap(); match steamdir.compat_tool(&titanfall2_steamid) { - Some(compat) => { - if !VALID_NORTHSTAR_PROTON_BUILDS - .contains(&compat.clone().name.unwrap().as_str()) - { - return Err( - "Titanfall2 was not configured to use a valid version of NorthstarProton or GE-Proton".to_string(), - ); - } - } + Some(_) => {} None => { return Err( "Titanfall2 was not configured to use a compatibility tool".to_string() diff --git a/src-tauri/src/northstar/profile.rs b/src-tauri/src/northstar/profile.rs index 78e734d0..b0c6c418 100644 --- a/src-tauri/src/northstar/profile.rs +++ b/src-tauri/src/northstar/profile.rs @@ -74,3 +74,20 @@ pub fn validate_profile(game_install: GameInstall, profile: String) -> bool { profile_dir.is_dir() } + +#[tauri::command] +pub fn delete_profile(game_install: GameInstall, profile: String) -> Result<(), String> { + // Check if the Profile actually exists + if !validate_profile(game_install.clone(), profile.clone()) { + return Err(format!("{} is not a valid Profile", profile)); + } + + log::info!("Deleting Profile {}", profile); + + let profile_path = format!("{}/{}", game_install.game_path, profile); + + match std::fs::remove_dir_all(profile_path) { + Ok(()) => Ok(()), + Err(err) => Err(format!("Failed to delete Profile: {}", err)), + } +} diff --git a/src-tauri/src/platform_specific/linux.rs b/src-tauri/src/platform_specific/linux.rs index 674f384b..706a4d22 100644 --- a/src-tauri/src/platform_specific/linux.rs +++ b/src-tauri/src/platform_specific/linux.rs @@ -3,6 +3,27 @@ use regex::Regex; use std::process::Command; +// I intend to add more linux related stuff to check here, so making a func +// for now tho it only checks `ldd --version` +// - salmon +pub fn linux_checks_librs() -> Result<(), String> { + // Perform various checks in terms of Linux compatibility + // Return early with error message if a check fails + + // check `ldd --version` to see if glibc is up to date for northstar proton + let min_required_ldd_version = 2.33; + let lddv = check_glibc_v(); + if lddv < min_required_ldd_version { + return Err(format!( + "GLIBC is not version {} or greater", + min_required_ldd_version + )); + }; + + // All checks passed + Ok(()) +} + fn get_proton_dir() -> Option<String> { let steam_dir = steamlocate::SteamDir::locate()?; let compat_dir = format!("{}/compatibilitytools.d/", steam_dir.path.display()); diff --git a/src-tauri/src/platform_specific/mod.rs b/src-tauri/src/platform_specific/mod.rs index 84bd478a..8dca9424 100644 --- a/src-tauri/src/platform_specific/mod.rs +++ b/src-tauri/src/platform_specific/mod.rs @@ -3,3 +3,55 @@ pub mod windows; #[cfg(target_os = "linux")] pub mod linux; + +/// Returns identifier of host OS FlightCore is running on +#[tauri::command] +pub fn get_host_os() -> String { + std::env::consts::OS.to_string() +} + +/// On Linux attempts to install NorthstarProton +/// On Windows simply returns an error message +#[tauri::command] +pub async fn install_northstar_proton_wrapper() -> Result<(), String> { + #[cfg(target_os = "linux")] + return linux::install_ns_proton().map_err(|err| err.to_string()); + + #[cfg(target_os = "windows")] + Err("Not supported on Windows".to_string()) +} + +#[tauri::command] +pub async fn uninstall_northstar_proton_wrapper() -> Result<(), String> { + #[cfg(target_os = "linux")] + return linux::uninstall_ns_proton(); + + #[cfg(target_os = "windows")] + Err("Not supported on Windows".to_string()) +} + +#[tauri::command] +pub async fn get_local_northstar_proton_wrapper_version() -> Result<String, String> { + #[cfg(target_os = "linux")] + return linux::get_local_ns_proton_version(); + + #[cfg(target_os = "windows")] + Err("Not supported on Windows".to_string()) +} + +/// Returns true if linux compatible +#[tauri::command] +pub async fn linux_checks() -> Result<(), String> { + // Different behaviour depending on OS + // MacOS is missing as it is not a target + // in turn this means this application will not build on MacOS. + #[cfg(target_os = "windows")] + { + Err("Not available on Windows".to_string()) + } + + #[cfg(target_os = "linux")] + { + linux::linux_checks_librs() + } +} diff --git a/src-tauri/src/platform_specific/windows.rs b/src-tauri/src/platform_specific/windows.rs index 899ab2cd..678e5be5 100644 --- a/src-tauri/src/platform_specific/windows.rs +++ b/src-tauri/src/platform_specific/windows.rs @@ -4,7 +4,7 @@ use anyhow::{anyhow, Result}; #[cfg(target_os = "windows")] use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey}; -use crate::check_is_valid_game_path; +use crate::repair_and_verify::check_is_valid_game_path; /// Gets Titanfall2 install location on Origin pub fn origin_install_location_detection() -> Result<String, anyhow::Error> { diff --git a/src-tauri/src/repair_and_verify/mod.rs b/src-tauri/src/repair_and_verify/mod.rs index 70abc127..c752a3ab 100644 --- a/src-tauri/src/repair_and_verify/mod.rs +++ b/src-tauri/src/repair_and_verify/mod.rs @@ -2,6 +2,31 @@ use crate::mod_management::{get_enabled_mods, rebuild_enabled_mods_json, set_mod /// Contains various functions to repair common issues and verifying installation use crate::{constants::CORE_MODS, GameInstall}; +/// Checks if is valid Titanfall2 install based on certain conditions +#[tauri::command] +pub async fn verify_install_location(game_path: String) -> bool { + match check_is_valid_game_path(&game_path) { + Ok(()) => true, + Err(err) => { + log::warn!("{}", err); + false + } + } +} + +/// Checks whether the provided path is a valid Titanfall2 gamepath by checking against a certain set of criteria +pub fn check_is_valid_game_path(game_install_path: &str) -> Result<(), String> { + let path_to_titanfall2_exe = format!("{game_install_path}/Titanfall2.exe"); + let is_correct_game_path = std::path::Path::new(&path_to_titanfall2_exe).exists(); + log::info!("Titanfall2.exe exists in path? {}", is_correct_game_path); + + // Exit early if wrong game path + if !is_correct_game_path { + return Err(format!("Incorrect game path \"{game_install_path}\"")); // Return error cause wrong game path + } + Ok(()) +} + /// Verifies Titanfall2 game files #[tauri::command] pub fn verify_game_files(game_install: GameInstall) -> Result<String, String> { @@ -32,6 +57,18 @@ pub fn disable_all_but_core(game_install: GameInstall) -> Result<(), String> { Ok(()) } +/// Installs the specified mod +#[tauri::command] +pub async fn clean_up_download_folder_wrapper( + game_install: GameInstall, + force: bool, +) -> Result<(), String> { + match clean_up_download_folder(&game_install, force) { + Ok(()) => Ok(()), + Err(err) => Err(err.to_string()), + } +} + /// Deletes download folder /// If `force` is FALSE, bails on non-empty folder /// If `force` is TRUE, deletes folder even if non-empty diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs index b21b2208..75555f3e 100644 --- a/src-tauri/src/util.rs +++ b/src-tauri/src/util.rs @@ -26,6 +26,49 @@ pub async fn is_debug_mode() -> bool { cfg!(debug_assertions) } +/// Returns the current version number as a string +#[tauri::command] +pub async fn get_flightcore_version_number() -> String { + let version = env!("CARGO_PKG_VERSION"); + if cfg!(debug_assertions) { + // Debugging enabled + format!("v{} (debug mode)", version) + } else { + // Debugging disabled + format!("v{}", version) + } +} + +/// Spawns repair window +#[tauri::command] +pub async fn open_repair_window(handle: tauri::AppHandle) -> Result<(), String> { + // Spawn new window + let repair_window = match tauri::WindowBuilder::new( + &handle, + "RepairWindow", + tauri::WindowUrl::App("/#/repair".into()), + ) + .build() + { + Ok(res) => res, + Err(err) => return Err(err.to_string()), + }; + + // Set window title + match repair_window.set_title("FlightCore Repair Window") { + Ok(()) => (), + Err(err) => return Err(err.to_string()), + }; + Ok(()) +} + +/// Closes all windows and exits application +#[tauri::command] +pub async fn close_application<R: tauri::Runtime>(app: tauri::AppHandle<R>) -> Result<(), String> { + app.exit(0); // Close application + Ok(()) +} + /// Fetches `/client/servers` endpoint from master server async fn fetch_server_list() -> Result<String, anyhow::Error> { let url = format!("{MASTER_SERVER_URL}{SERVER_BROWSER_ENDPOINT}"); @@ -182,3 +225,12 @@ pub fn move_dir_all( } Ok(()) } + +/// Helps with converting release candidate numbers which are different on Thunderstore +/// due to restrictions imposed by the platform +pub fn convert_release_candidate_number(version_number: String) -> String { + // This simply converts `-rc` to `0` + // Works as intended for RCs < 10, e.g. `v1.9.2-rc1` -> `v1.9.201` + // Doesn't work for larger numbers, e.g. `v1.9.2-rc11` -> `v1.9.2011` (should be `v1.9.211`) + version_number.replace("-rc", "0").replace("00", "") +} |