diff --git a/src-tauri/src/northstar/mod.rs b/src-tauri/src/northstar/mod.rs index ea4f4cde1..1f64f3405 100644 --- a/src-tauri/src/northstar/mod.rs +++ b/src-tauri/src/northstar/mod.rs @@ -154,14 +154,16 @@ pub fn get_northstar_version_number(game_install: GameInstall) -> Result, launch_via_steam: Option, bypass_checks: Option, ) -> Result { dbg!(game_install.clone()); + println!("Launch arguments: {:?}", launch_args); let launch_via_steam = launch_via_steam.unwrap_or(false); if launch_via_steam { - return launch_northstar_steam(game_install, bypass_checks); + return launch_northstar_steam(game_install, launch_args, bypass_checks); } let host_os = get_host_os(); @@ -176,7 +178,7 @@ pub fn launch_northstar( )); } - return launch_northstar_steam(game_install, bypass_checks); + return launch_northstar_steam(game_install, launch_args, bypass_checks); } let bypass_checks = bypass_checks.unwrap_or(false); @@ -212,9 +214,11 @@ pub fn launch_northstar( { let ns_exe_path = format!("{}/NorthstarLauncher.exe", game_install.game_path); let ns_profile_arg = format!("-profile={}", game_install.profile); + let mut arguments = vec!["/C", "start", "", &ns_exe_path, &ns_profile_arg]; + arguments.extend(launch_args); let _output = std::process::Command::new("C:\\Windows\\System32\\cmd.exe") - .args(["/C", "start", "", &ns_exe_path, &ns_profile_arg]) + .args(arguments) .spawn() .expect("failed to execute process"); return Ok("Launched game".to_string()); @@ -230,6 +234,7 @@ pub fn launch_northstar( /// Prepare Northstar and Launch through Steam using the Browser Protocol pub fn launch_northstar_steam( game_install: GameInstall, + launch_args: Vec<&str>, _bypass_checks: Option, ) -> Result { if !matches!(game_install.install_type, InstallType::STEAM) { @@ -262,8 +267,10 @@ pub fn launch_northstar_steam( } match open::that(format!( - "steam://run/{}//-profile={} --northstar/", - TITANFALL2_STEAM_ID, game_install.profile + "steam://run/{}//-profile={} --northstar/ {}", + TITANFALL2_STEAM_ID, + game_install.profile, + launch_args.join(" ") )) { Ok(()) => Ok("Started game".to_string()), Err(_err) => Err("Failed to launch Titanfall 2 via Steam".to_string()), diff --git a/src-vue/src/components/LaunchArgumentsSelector.vue b/src-vue/src/components/LaunchArgumentsSelector.vue new file mode 100644 index 000000000..436b65b16 --- /dev/null +++ b/src-vue/src/components/LaunchArgumentsSelector.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/src-vue/src/i18n/lang/en.json b/src-vue/src/i18n/lang/en.json index e0460fd1f..6a48ab750 100644 --- a/src-vue/src/i18n/lang/en.json +++ b/src-vue/src/i18n/lang/en.json @@ -144,6 +144,23 @@ "reinstall_text": "Please wait", "reinstall_success": "Successfully reinstalled Northstar" } + }, + + "launch_args": { + "title": "Launch arguments", + "new_arg_btn": "+ New launch argument", + "select_game_language": "Select game language", + "descriptions": { + "disablelogs": "Disable logging and creation of log files", + "vanilla": "Disables Northstar loading", + "northstar": "Enables Northstar loading", + "dedicated": "Starts a dedicated server without video output", + "waitfordebugger": "Waits for debugger to connect before launching game", + "enablechathooks": "Enables the use of chathooks for use by mods", + "noplugins": "Disables the plugin system", + "novid": "Disables startup videos", + "nosound": "Disables all game sounds" + } } }, diff --git a/src-vue/src/i18n/lang/fr.json b/src-vue/src/i18n/lang/fr.json index d2de46b01..07dd6694b 100644 --- a/src-vue/src/i18n/lang/fr.json +++ b/src-vue/src/i18n/lang/fr.json @@ -128,6 +128,22 @@ "delete": "Supprimer", "delete_confirm": "Voulez-vous vraiment supprimer ce profil ?" } + }, + + "launch_args": { + "title": "Paramètres de démarrage", + "new_arg_btn": "+ Nouveau paramètre", + "descriptions": { + "disablelogs": "Désactive la journalisation et la création de journaux", + "vanilla": "Désactive le chargement de Northstar", + "northstar": "Active le chargement de Northstar", + "dedicated": "Démarre un serveur dédié sans sortie graphique", + "waitfordebugger": "Attend la connexion au débuggueur avant de lancer le jeu", + "enablechathooks": "Active les chathooks pour les mods", + "noplugins": "Désactive le système de plugins", + "novid": "Désactive les vidéos au démarrage", + "nosound": "Désactive tous les sons du jeu" + } } }, "notification": { diff --git a/src-vue/src/main.ts b/src-vue/src/main.ts index 73219c9d7..60eb337d3 100644 --- a/src-vue/src/main.ts +++ b/src-vue/src/main.ts @@ -64,5 +64,7 @@ export const router = createRouter({ }); app.use(router); +// Store keys +export const argumentsStoreKey = 'launch_arguments'; app.mount('#app') diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts index a1a67e2b8..e69a65050 100644 --- a/src-vue/src/plugins/store.ts +++ b/src-vue/src/plugins/store.ts @@ -11,7 +11,7 @@ import { NorthstarState } from '../utils/NorthstarState'; import { appDir } from '@tauri-apps/api/path'; import { open } from '@tauri-apps/api/dialog'; import { Store } from 'tauri-plugin-store-api'; -import { router } from "../main"; +import {argumentsStoreKey, router} from "../main"; import { ReleaseInfo } from "../../../src-tauri/bindings/ReleaseInfo"; import { ThunderstoreMod } from "../../../src-tauri/bindings/ThunderstoreMod"; import { NorthstarMod } from "../../../src-tauri/bindings/NorthstarMod"; @@ -173,8 +173,11 @@ export const store = createStore({ } }, async launchGame(state: any, no_checks = false) { + // Launch arguments + const fileArgs: string[] = await persistentStore.get(argumentsStoreKey) ?? []; + if (no_checks) { - await invoke("launch_northstar", { gameInstall: state.game_install, bypassChecks: no_checks }) + await invoke("launch_northstar", { gameInstall: state.game_install, launchArgs: fileArgs, bypassChecks: no_checks }) .then((message) => { console.log("Launched with bypassed checks"); console.log(message); @@ -224,7 +227,7 @@ export const store = createStore({ // Game is ready to play. case NorthstarState.READY_TO_PLAY: - await invoke("launch_northstar", { gameInstall: state.game_install }) + await invoke("launch_northstar", { gameInstall: state.game_install, launchArgs: fileArgs }) .then((message) => { console.log(message); // NorthstarState.RUNNING @@ -241,7 +244,10 @@ export const store = createStore({ } }, async launchGameSteam(state: any, no_checks = false) { - await invoke("launch_northstar", { gameInstall: state.game_install, launchViaSteam: true, bypassChecks: no_checks }) + // Launch arguments + const fileArgs: string[] = await persistentStore.get(argumentsStoreKey) ?? []; + + await invoke("launch_northstar", { gameInstall: state.game_install, launchArgs: fileArgs, launchViaSteam: true, bypassChecks: no_checks }) .then((message) => { showNotification('Success'); }) diff --git a/src-vue/src/utils/LaunchArgument.ts b/src-vue/src/utils/LaunchArgument.ts new file mode 100644 index 000000000..55b907bd4 --- /dev/null +++ b/src-vue/src/utils/LaunchArgument.ts @@ -0,0 +1,9 @@ +export class LaunchArgument { + public argumentName: string; + public i18nEntry: string; + + constructor(argumentName: string, i18nEntry: string = '') { + this.argumentName = argumentName; + this.i18nEntry = i18nEntry; + } +} \ No newline at end of file diff --git a/src-vue/src/views/SettingsView.vue b/src-vue/src/views/SettingsView.vue index 16b894d5c..86113b831 100644 --- a/src-vue/src/views/SettingsView.vue +++ b/src-vue/src/views/SettingsView.vue @@ -67,6 +67,12 @@ + +
+

{{ $t('settings.launch_args.title') }}

+ +
+

{{ $t('settings.nb_ts_mods_per_page') }}

@@ -140,6 +146,7 @@ import { ReleaseCanal } from "../utils/ReleaseCanal"; import { Store } from 'tauri-plugin-store-api'; import { showErrorNotification, showNotification } from "../utils/ui"; import LanguageSelector from "../components/LanguageSelector.vue"; +import LaunchArgumentsSelector from "../components/LaunchArgumentsSelector.vue"; const persistentStore = new Store('flight-core-settings.json'); import { open } from '@tauri-apps/api/shell'; import { i18n } from '../main'; @@ -148,7 +155,8 @@ import { ElMessageBox } from 'element-plus' export default defineComponent({ name: "SettingsView", components: { - LanguageSelector + LanguageSelector, + LaunchArgumentsSelector }, data() { return {