Skip to content

Commit

Permalink
Merge branch 'main' into chore/bump-upload-artifact-action
Browse files Browse the repository at this point in the history
  • Loading branch information
GeckoEidechse authored Aug 8, 2024
2 parents 3362cd9 + 3cab2a7 commit 060c27a
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 26 deletions.
44 changes: 22 additions & 22 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
45 changes: 44 additions & 1 deletion src-tauri/src/github/release_notes.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rand::prelude::SliceRandom;
use serde::{Deserialize, Serialize};
use std::vec::Vec;
use ts_rs::TS;
Expand Down Expand Up @@ -168,9 +169,51 @@ pub async fn generate_release_note_announcement() -> Result<String, String> {
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}
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 11 additions & 1 deletion src-tauri/src/mod_management/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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?;

Expand Down
10 changes: 10 additions & 0 deletions src-tauri/src/platform_specific/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ pub async fn get_local_northstar_proton_wrapper_version() -> Result<String, Stri
#[cfg(target_os = "windows")]
Err("Not supported on Windows".to_string())
}

/// Check whether the current device might be behind a CGNAT
#[tauri::command]
pub async fn check_cgnat() -> Result<String, String> {
#[cfg(target_os = "linux")]
return Err("Not supported on Linux".to_string());

#[cfg(target_os = "windows")]
windows::check_cgnat().await
}
70 changes: 70 additions & 0 deletions src-tauri/src/platform_specific/windows.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -32,3 +33,72 @@ pub fn origin_install_location_detection() -> Result<String, anyhow::Error> {

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<String, String> {
// 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::<Ipv4Addr>().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<usize, String> {
// Ensure valid IPv4 address to avoid prevent command injection
assert!(target_ip.parse::<Ipv4Addr>().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))
}
}
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "FlightCore",
"version": "2.23.2"
"version": "2.24.0"
},
"tauri": {
"allowlist": {
Expand Down
12 changes: 12 additions & 0 deletions src-vue/src/views/DeveloperView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@

<h3>Repair:</h3>

<el-button type="primary" @click="checkCgnat">
Run tracert and collect hop count
</el-button>

<el-button type="primary" @click="getInstalledMods">
Get installed mods
Expand Down Expand Up @@ -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<string>("check_cgnat")
.then((message) => {
showNotification(message);
})
.catch((error) => {
showErrorNotification(error);
});
},
async copyReleaseNotesToClipboard() {
navigator.clipboard.writeText(this.release_notes_text)
.then(() => {
Expand Down

0 comments on commit 060c27a

Please sign in to comment.