1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
//! This module deals with handling things around Northstar such as
//! - getting version number
pub mod install;
use crate::util::check_origin_running;
use crate::{constants::CORE_MODS, get_host_os, GameInstall, InstallType};
use anyhow::anyhow;
/// 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"))?;
let parsed_json: serde_json::Value = serde_json::from_str(&data)?;
let mod_version_number = match parsed_json.get("Version").and_then(|value| value.as_str()) {
Some(version_number) => version_number,
None => return Err(anyhow!("No version number found")),
};
log::info!("{}", mod_version_number);
Ok(mod_version_number.to_string())
}
/// Returns the current Northstar version number as a string
#[tauri::command]
pub fn get_northstar_version_number(game_path: &str) -> Result<String, String> {
log::info!("{}", game_path);
// TODO:
// Check if NorthstarLauncher.exe exists and check its version number
let profile_folder = "R2Northstar";
let initial_version_number = match check_mod_version_number(&format!(
"{game_path}/{profile_folder}/mods/{}",
CORE_MODS[0]
)) {
Ok(version_number) => version_number,
Err(err) => return Err(err.to_string()),
};
for core_mod in CORE_MODS {
let current_version_number = match check_mod_version_number(&format!(
"{game_path}/{profile_folder}/mods/{core_mod}",
)) {
Ok(version_number) => version_number,
Err(err) => return Err(err.to_string()),
};
if current_version_number != initial_version_number {
// We have a version number mismatch
return Err("Found version number mismatch".to_string());
}
}
log::info!("All mods same version");
Ok(initial_version_number)
}
/// Launches Northstar
#[tauri::command]
pub fn launch_northstar(
game_install: GameInstall,
bypass_checks: Option<bool>,
) -> Result<String, String> {
dbg!(game_install.clone());
let host_os = get_host_os();
// Explicitly fail early certain (currently) unsupported install setups
if host_os != "windows"
|| !(matches!(game_install.install_type, InstallType::STEAM)
|| matches!(game_install.install_type, InstallType::ORIGIN)
|| matches!(game_install.install_type, InstallType::UNKNOWN))
{
return Err(format!(
"Not yet implemented for \"{}\" with Titanfall2 installed via \"{:?}\"",
get_host_os(),
game_install.install_type
));
}
let bypass_checks = bypass_checks.unwrap_or(false);
// Only check guards if bypassing checks is not enabled
if !bypass_checks {
// Some safety checks before, should have more in the future
if get_northstar_version_number(&game_install.game_path).is_err() {
return Err(anyhow!("Not all checks were met").to_string());
}
// Require Origin to be running to launch Northstar
let origin_is_running = check_origin_running();
if !origin_is_running {
return Err(
anyhow!("Origin not running, start Origin before launching Northstar").to_string(),
);
}
}
// Switch to Titanfall2 directory for launching
// NorthstarLauncher.exe expects to be run from that folder
if std::env::set_current_dir(game_install.game_path.clone()).is_err() {
// We failed to get to Titanfall2 directory
return Err(anyhow!("Couldn't access Titanfall2 directory").to_string());
}
// Only Windows with Steam or Origin are supported at the moment
if host_os == "windows"
&& (matches!(game_install.install_type, InstallType::STEAM)
|| matches!(game_install.install_type, InstallType::ORIGIN)
|| matches!(game_install.install_type, InstallType::UNKNOWN))
{
let ns_exe_path = format!("{}/NorthstarLauncher.exe", game_install.game_path);
let _output = std::process::Command::new("C:\\Windows\\System32\\cmd.exe")
.args(["/C", "start", "", &ns_exe_path])
.spawn()
.expect("failed to execute process");
return Ok("Launched game".to_string());
}
Err(format!(
"Not yet implemented for {:?} on {}",
game_install.install_type,
get_host_os()
))
}
|