From cd13d0d15b7a6c6a59bde31322229bccdb7bae83 Mon Sep 17 00:00:00 2001 From: GeckoEidechse Date: Fri, 2 Aug 2024 11:08:29 +0200 Subject: [PATCH 1/5] chore: Bump FlightCore version to 2.24.0 --- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index db7379e2..def8dea7 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1165,7 +1165,7 @@ dependencies = [ [[package]] name = "flightcore" -version = "2.23.2" +version = "2.24.0" dependencies = [ "anyhow", "async-recursion", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c9a559a7..4d28ca2e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flightcore" -version = "2.23.2" +version = "2.24.0" description = "Mod-manager for Northstar" authors = ["https://github.com/R2NorthstarTools/FlightCore/graphs/contributors"] license = "MIT" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 63721461..182c907d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "FlightCore", - "version": "2.23.2" + "version": "2.24.0" }, "tauri": { "allowlist": { From 878f50ccd042f6768646131f29323d25c5142519 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:46:52 +0200 Subject: [PATCH 2/5] chore: bump tokio from 1.38.0 to 1.39.2 in /src-tauri (#991) Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.38.0 to 1.39.2. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.38.0...tokio-1.39.2) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src-tauri/Cargo.lock | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index def8dea7..376e948e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1716,9 +1716,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -2504,13 +2504,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2685,16 +2686,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_enum" version = "0.5.11" @@ -5041,28 +5032,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", @@ -5921,6 +5911,15 @@ dependencies = [ "windows-targets 0.48.1", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" From 1ac4198ec988ac49cb7740336df7a43bab3fbe52 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Sat, 3 Aug 2024 00:13:03 +0200 Subject: [PATCH 3/5] feat: Pick random adjective when generating release notes (#995) from a list of predefined ones --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 2 ++ src-tauri/src/github/release_notes.rs | 45 ++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 376e948e..1e7eacbc 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1179,6 +1179,7 @@ dependencies = [ "octocrab", "open 5.3.0", "pretty_env_logger", + "rand 0.8.5", "regex", "remove-markdown-links", "reqwest 0.11.27", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4d28ca2e..210c76b8 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -65,6 +65,8 @@ semver = "1.0" # simplified filesystem access glob = "0.3.1" dirs = "5" +# Random number stuff +rand = "0.8.5" # Interacting with GitHub octocrab = "0.38.0" diff --git a/src-tauri/src/github/release_notes.rs b/src-tauri/src/github/release_notes.rs index e3a14537..4adfb24b 100644 --- a/src-tauri/src/github/release_notes.rs +++ b/src-tauri/src/github/release_notes.rs @@ -1,3 +1,4 @@ +use rand::prelude::SliceRandom; use serde::{Deserialize, Serialize}; use std::vec::Vec; use ts_rs::TS; @@ -168,9 +169,51 @@ pub async fn generate_release_note_announcement() -> Result { let modders_info = "Mod compatibility should not be impacted"; let server_hosters_info = "REPLACE ME"; + let mut rng = rand::thread_rng(); + let attributes = vec![ + "adorable", + "amazing", + "beautiful", + "blithsome", + "brilliant", + "compassionate", + "dazzling", + "delightful", + "distinguished", + "elegant", + "enigmatic", + "enthusiastic", + "fashionable", + "fortuitous", + "friendly", + "generous", + "gleeful", + "gorgeous", + "handsome", + "lively", + "lovely", + "lucky", + "lustrous", + "marvelous", + "merry", + "mirthful", + "phantasmagorical", + "pretty", + "propitious", + "ravishing", + "sincere", + "sophisticated fellow", + "stupendous", + "vivacious", + "wonderful", + "zestful", + ]; + + let selected_attribute = attributes.choose(&mut rng).unwrap(); + // Build announcement string let return_string = format!( - r"Hello beautiful people <3 + r"Hello {selected_attribute} people <3 **Northstar `{current_ns_version}` is out!** {general_info} From 863a7fbedfb8d443a528e7475edb5de541499ce9 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Sat, 3 Aug 2024 02:00:54 +0200 Subject: [PATCH 4/5] feat: Add initial CGNAT check logic (#969) Adds some logic that gets external IP and runs tracert to count the number of hops to said IP address. The goal is to have an automated way to check for CGNAT. --- src-tauri/src/main.rs | 1 + src-tauri/src/platform_specific/mod.rs | 10 ++++ src-tauri/src/platform_specific/windows.rs | 70 ++++++++++++++++++++++ src-vue/src/views/DeveloperView.vue | 12 ++++ 4 files changed, 93 insertions(+) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index ee7da27f..a9f484f5 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -136,6 +136,7 @@ fn main() { northstar::profile::delete_profile, northstar::profile::fetch_profiles, northstar::profile::validate_profile, + platform_specific::check_cgnat, platform_specific::get_host_os, platform_specific::get_local_northstar_proton_wrapper_version, platform_specific::install_northstar_proton_wrapper, diff --git a/src-tauri/src/platform_specific/mod.rs b/src-tauri/src/platform_specific/mod.rs index 6fdb1ed1..4e0514d4 100644 --- a/src-tauri/src/platform_specific/mod.rs +++ b/src-tauri/src/platform_specific/mod.rs @@ -38,3 +38,13 @@ pub async fn get_local_northstar_proton_wrapper_version() -> Result Result { + #[cfg(target_os = "linux")] + return Err("Not supported on Linux".to_string()); + + #[cfg(target_os = "windows")] + windows::check_cgnat().await +} diff --git a/src-tauri/src/platform_specific/windows.rs b/src-tauri/src/platform_specific/windows.rs index 678e5be5..fc6aab5d 100644 --- a/src-tauri/src/platform_specific/windows.rs +++ b/src-tauri/src/platform_specific/windows.rs @@ -1,5 +1,6 @@ /// Windows specific code use anyhow::{anyhow, Result}; +use std::net::Ipv4Addr; #[cfg(target_os = "windows")] use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey}; @@ -32,3 +33,72 @@ pub fn origin_install_location_detection() -> Result { Err(anyhow!("No Origin / EA App install path found")) } + +/// Check whether the current device might be behind a CGNAT +pub async fn check_cgnat() -> Result { + // Use external service to grap IP + let url = "https://api.ipify.org"; + let response = reqwest::get(url).await.unwrap().text().await.unwrap(); + + // Check if valid IPv4 address and return early if not + if response.parse::().is_err() { + return Err(format!("Not valid IPv4 address: {}", response)); + } + + let hops_count = run_tracert(&response)?; + Ok(format!("Counted {} hops to {}", hops_count, response)) +} + +/// Count number of hops in tracert output +fn count_hops(output: &str) -> usize { + // Split the output into lines + let lines: Vec<&str> = output.lines().collect(); + + // Filter lines that appear to represent hops + let hop_lines: Vec<&str> = lines + .iter() + .filter(|&line| line.contains("ms") || line.contains("*")) // TODO check if it contains just the `ms` surrounded by whitespace, otherwise it might falsely pick up some domain names as well + .cloned() + .collect(); + + // Return the number of hops + hop_lines.len() +} + +/// Run `tracert` +fn run_tracert(target_ip: &str) -> Result { + // Ensure valid IPv4 address to avoid prevent command injection + assert!(target_ip.parse::().is_ok()); + + // Execute the `tracert` command + let output = match std::process::Command::new("tracert") + .arg("-4") // Force IPv4 + .arg("-d") // Prevent resolving intermediate IP addresses + .arg("-w") // Set timeout to 1 second + .arg("1000") + .arg("-h") // Set max hop count + .arg("5") + .arg(target_ip) + .output() + { + Ok(res) => res, + Err(err) => return Err(format!("Failed running tracert: {}", err)), + }; + + // Check if the command was successful + if output.status.success() { + // Convert the output to a string + let stdout = + std::str::from_utf8(&output.stdout).expect("Invalid UTF-8 sequence in command output"); + println!("{}", stdout); + + // Count the number of hops + let hop_count = count_hops(stdout); + Ok(hop_count) + } else { + let stderr = std::str::from_utf8(&output.stderr) + .expect("Invalid UTF-8 sequence in command error output"); + println!("{}", stderr); + Err(format!("Failed collecting tracert output: {}", stderr)) + } +} diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue index a08c73f3..19214157 100644 --- a/src-vue/src/views/DeveloperView.vue +++ b/src-vue/src/views/DeveloperView.vue @@ -65,6 +65,9 @@

Repair:

+ + Run tracert and collect hop count + Get installed mods @@ -330,6 +333,15 @@ export default defineComponent({ .then((message) => { showNotification(`NSProton Version`, message as string); }) .catch((error) => { showNotification(`Error`, error, "error"); }) }, + async checkCgnat() { + await invoke("check_cgnat") + .then((message) => { + showNotification(message); + }) + .catch((error) => { + showErrorNotification(error); + }); + }, async copyReleaseNotesToClipboard() { navigator.clipboard.writeText(this.release_notes_text) .then(() => { From 3cab2a7852fdc4663c8c7f4df6a52b831e610e92 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:09:40 +0200 Subject: [PATCH 5/5] feat: Prevent installation of Vanilla+ mod (#996) as it has special installation requirements that makes it not installable like common Northstar mods. --- src-tauri/src/constants.rs | 3 +++ src-tauri/src/mod_management/mod.rs | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 47eeef19..3ad2d6e8 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -26,6 +26,9 @@ pub const BLACKLISTED_MODS: [&str; 3] = [ "ebkr-r2modman", ]; +/// List of Thunderstoremods that have some specific install requirements that makes them different from standard mods +pub const MODS_WITH_SPECIAL_REQUIREMENTS: [&str; 1] = ["NanohmProtogen-VanillaPlus"]; + /// Order in which the sections for release notes should be displayed pub const SECTION_ORDER: [&str; 11] = [ "feat", "fix", "docs", "style", "refactor", "build", "test", "i18n", "ci", "chore", "other", diff --git a/src-tauri/src/mod_management/mod.rs b/src-tauri/src/mod_management/mod.rs index ebbcf431..2a018920 100644 --- a/src-tauri/src/mod_management/mod.rs +++ b/src-tauri/src/mod_management/mod.rs @@ -1,6 +1,6 @@ // This file contains various mod management functions -use crate::constants::{BLACKLISTED_MODS, CORE_MODS}; +use crate::constants::{BLACKLISTED_MODS, CORE_MODS, MODS_WITH_SPECIAL_REQUIREMENTS}; use async_recursion::async_recursion; use thermite::prelude::ThermiteError; @@ -609,6 +609,16 @@ pub async fn fc_download_mod_and_install( } } + // Prevent installing mods that have specific install requirements + for special_mod in MODS_WITH_SPECIAL_REQUIREMENTS { + if thunderstore_mod_string.contains(special_mod) { + return Err(format!( + "{} has special install requirements and cannot be installed with FlightCore", + thunderstore_mod_string + )); + } + } + // Get download URL for the specified mod let download_url = get_ns_mod_download_url(thunderstore_mod_string).await?;