aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-tauri/Cargo.lock56
-rw-r--r--src-tauri/Cargo.toml4
-rw-r--r--src-tauri/src/constants.rs3
-rw-r--r--src-tauri/src/lib.rs99
-rw-r--r--src-tauri/src/main.rs10
-rw-r--r--src-vue/src/plugins/store.ts26
-rw-r--r--src-vue/src/views/DeveloperView.vue7
7 files changed, 191 insertions, 14 deletions
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index ec1756b4..733831e4 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -97,6 +97,7 @@ dependencies = [
"json5",
"libthermite",
"log",
+ "open",
"pretty_env_logger",
"regex",
"reqwest",
@@ -800,16 +801,16 @@ version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210"
dependencies = [
- "dirs-sys",
+ "dirs-sys 0.3.7",
]
[[package]]
name = "dirs"
-version = "3.0.2"
+version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
+checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd"
dependencies = [
- "dirs-sys",
+ "dirs-sys 0.4.0",
]
[[package]]
@@ -834,6 +835,17 @@ dependencies = [
]
[[package]]
+name = "dirs-sys"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b"
+dependencies = [
+ "libc",
+ "redox_users",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1136,7 +1148,7 @@ dependencies = [
"serde_yaml",
"sysinfo 0.23.13",
"url",
- "winreg",
+ "winreg 0.10.1",
]
[[package]]
@@ -1865,6 +1877,20 @@ dependencies = [
]
[[package]]
+name = "keyvalues-serde"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da419ac133bb3ddf0dbf9c12fcc0ce01d994fcb65f6f1713faf15cc689320b5f"
+dependencies = [
+ "keyvalues-parser",
+ "once_cell",
+ "paste",
+ "regex",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
name = "kuchiki"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3054,7 +3080,7 @@ dependencies = [
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
- "winreg",
+ "winreg 0.10.1",
]
[[package]]
@@ -3652,14 +3678,16 @@ dependencies = [
[[package]]
name = "steamlocate"
-version = "1.1.1"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf364a9446f9f4423694ad8db5be8c478088970138e557ff2ddb3167fb0a2944"
+checksum = "6b3962619891cd4c87dc0ae9332b97285eb59ab7cf65c9bec3fba62188390e74"
dependencies = [
"dirs",
"keyvalues-parser",
+ "keyvalues-serde",
+ "serde",
"steamy-vdf",
- "winreg",
+ "winreg 0.11.0",
]
[[package]]
@@ -5003,6 +5031,16 @@ dependencies = [
]
[[package]]
+name = "winreg"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
name = "winres"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index c7d52d89..2267c239 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -29,7 +29,7 @@ tokio = { version = "1", features = ["full"] }
sentry = "0.30"
sentry-log = "0.30.0"
# Find steam games
-steamlocate = "1.0.2"
+steamlocate = "1.2"
# Error messages
anyhow = "1.0"
# libthermite for Northstar/mod install handling
@@ -61,6 +61,8 @@ pretty_env_logger = "0.4.0"
log = "0.4.17"
# Extracting zip files easily
zip-extract = "0.1.2"
+# open urls
+open = "3.2.0"
[features]
# by default Tauri runs in production mode
diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs
index 0f4e9ab4..8c88df1e 100644
--- a/src-tauri/src/constants.rs
+++ b/src-tauri/src/constants.rs
@@ -29,6 +29,9 @@ pub const BLACKLISTED_MODS: [&str; 3] = [
// Titanfall2 game IDs on Origin/EA-App
pub const TITANFALL2_ORIGIN_IDS: [&str; 2] = ["Origin.OFR.50.0001452", "Origin.OFR.50.0001456"];
+// Titanfall2 Steam App ID
+pub const TITANFALL2_STEAM_ID: &str = "1237970";
+
// Order in which the sections for release notes should be displayed
pub const SECTION_ORDER: [&str; 9] = [
"feat", "fix", "docs", "style", "refactor", "build", "test", "chore", "other",
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index ff1445e5..a3553448 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -1,4 +1,4 @@
-use std::env;
+use std::{env, fs, path::Path, time::Duration};
use anyhow::{anyhow, Context, Result};
@@ -14,11 +14,14 @@ use platform_specific::linux;
use serde::{Deserialize, Serialize};
use sysinfo::SystemExt;
+use tokio::time::sleep;
use ts_rs::TS;
use zip::ZipArchive;
use northstar::get_northstar_version_number;
+use crate::constants::TITANFALL2_STEAM_ID;
+
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum InstallType {
STEAM,
@@ -92,7 +95,7 @@ pub fn find_game_install_location() -> Result<GameInstall, String> {
// Attempt parsing Steam library directly
match steamlocate::SteamDir::locate() {
Some(mut steamdir) => {
- let titanfall2_steamid = 1237970;
+ let titanfall2_steamid = TITANFALL2_STEAM_ID.parse().unwrap();
match steamdir.app(&titanfall2_steamid) {
Some(app) => {
// println!("{:#?}", app);
@@ -328,6 +331,93 @@ pub fn launch_northstar(
))
}
+/// Prepare Northstar and Launch through Steam using the Browser Protocol
+pub fn launch_northstar_steam(
+ game_install: GameInstall,
+ _bypass_checks: Option<bool>,
+) -> Result<String, String> {
+ if !matches!(game_install.install_type, InstallType::STEAM) {
+ return Err("Titanfall2 was not installed via Steam".to_string());
+ }
+
+ match steamlocate::SteamDir::locate() {
+ Some(mut steamdir) => {
+ if get_host_os() != "windows" {
+ let titanfall2_steamid: u32 = TITANFALL2_STEAM_ID.parse().unwrap();
+ match steamdir.compat_tool(&titanfall2_steamid) {
+ Some(compat) => {
+ if !compat
+ .name
+ .clone()
+ .unwrap()
+ .to_ascii_lowercase()
+ .contains("northstarproton")
+ {
+ return Err(
+ "Titanfall2 was not configured to use NorthstarProton".to_string()
+ );
+ }
+ }
+ None => {
+ return Err(
+ "Titanfall2 was not configured to use a compatibility tool".to_string()
+ );
+ }
+ }
+ }
+ }
+ None => {
+ return Err("Couldn't access Titanfall2 directory".to_string());
+ }
+ }
+
+ // Switch to Titanfall2 directory to set everything up
+ if std::env::set_current_dir(game_install.game_path).is_err() {
+ // We failed to get to Titanfall2 directory
+ return Err("Couldn't access Titanfall2 directory".to_string());
+ }
+
+ let run_northstar = "run_northstar.txt";
+ let run_northstar_bak = "run_northstar.txt.bak";
+
+ if Path::new(run_northstar).exists() {
+ // rename should ovewrite existing files
+ fs::rename(run_northstar, run_northstar_bak).unwrap();
+ }
+
+ // Passing arguments gives users a prompt, so we use run_northstar.txt
+ fs::write(run_northstar, b"1").unwrap();
+
+ let retval = match open::that(format!("steam://run/{}/", TITANFALL2_STEAM_ID)) {
+ Ok(()) => Ok("Started game".to_string()),
+ Err(_err) => Err("Failed to launch Titanfall 2 via Steam".to_string()),
+ };
+
+ let is_err = retval.is_err();
+
+ // Handle the rest in the backround
+ tauri::async_runtime::spawn(async move {
+ // Starting the EA app and Titanfall might take a good minute or three
+ let mut wait_countdown = 60 * 3;
+ while wait_countdown > 0 && !check_northstar_running() && !is_err {
+ sleep(Duration::from_millis(1000)).await;
+ wait_countdown -= 1;
+ }
+
+ // Northstar may be running, but it may not have loaded the file yet
+ sleep(Duration::from_millis(2000)).await;
+
+ // intentionally ignore Result
+ let _ = fs::remove_file(run_northstar);
+
+ if Path::new(run_northstar_bak).exists() {
+ fs::rename(run_northstar_bak, run_northstar).unwrap();
+ }
+ });
+
+ retval
+}
+
pub fn check_origin_running() -> bool {
let s = sysinfo::System::new_all();
s.processes_by_name("Origin.exe").next().is_some()
@@ -336,10 +426,11 @@ pub fn check_origin_running() -> bool {
/// Checks if Northstar process is running
pub fn check_northstar_running() -> bool {
- sysinfo::System::new_all()
- .processes_by_name("NorthstarLauncher.exe")
+ let s = sysinfo::System::new_all();
+ s.processes_by_name("NorthstarLauncher.exe")
.next()
.is_some()
+ || s.processes_by_name("Titanfall2.exe").next().is_some()
}
/// Helps with converting release candidate numbers which are different on Thunderstore
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 21045db1..16b951ec 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -121,6 +121,7 @@ fn main() {
install_northstar_caller,
update_northstar_caller,
launch_northstar_caller,
+ launch_northstar_steam_caller,
check_is_flightcore_outdated_caller,
get_log_list,
verify_game_files,
@@ -324,6 +325,15 @@ async fn launch_northstar_caller(
}
#[tauri::command]
+/// Launches Northstar
+async fn launch_northstar_steam_caller(
+ game_install: GameInstall,
+ bypass_checks: Option<bool>,
+) -> Result<String, String> {
+ launch_northstar_steam(game_install, bypass_checks)
+}
+
+#[tauri::command]
/// Installs the specified mod
async fn install_mod_caller(
game_install: GameInstall,
diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts
index 60208879..cdbd6738 100644
--- a/src-vue/src/plugins/store.ts
+++ b/src-vue/src/plugins/store.ts
@@ -243,6 +243,32 @@ export const store = createStore<FlightCoreStore>({
break;
}
},
+ async launchGameSteam(state: any, no_checks = false) {
+ let game_install = {
+ game_path: state.game_path,
+ install_type: state.install_type
+ } as GameInstall;
+
+ await invoke("launch_northstar_steam_caller", { gameInstall: game_install, bypassChecks: no_checks })
+ .then((message) => {
+ ElNotification({
+ title: 'Success',
+ type: 'success',
+ position: 'bottom-right'
+ });
+ })
+ .catch((error) => {
+ console.error(error);
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ });
+
+ return;
+ },
async fetchReleaseNotes(state: FlightCoreStore) {
if (state.releaseNotes.length !== 0) return;
state.releaseNotes = await invoke("get_northstar_release_notes");
diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue
index bca473fb..7712756c 100644
--- a/src-vue/src/views/DeveloperView.vue
+++ b/src-vue/src/views/DeveloperView.vue
@@ -59,6 +59,10 @@
Launch Northstar (bypass all checks)
</el-button>
+ <el-button type="primary" @click="launchGameViaSteam">
+ Launch Northstar via Steam
+ </el-button>
+
<h3>Mod install:</h3>
<el-input v-model="mod_to_install_field_string" placeholder="Please input Thunderstore dependency string (example: AuthorName-ModName-1.2.3)" clearable />
@@ -156,6 +160,9 @@ export default defineComponent({
async launchGameWithoutChecks() {
this.$store.commit('launchGame', true);
},
+ async launchGameViaSteam() {
+ this.$store.commit('launchGameSteam', true);
+ },
async getInstalledMods() {
let game_install = {
game_path: this.$store.state.game_path,