From 469ba5f57472a554d3889fdecae76f40100ef6ec Mon Sep 17 00:00:00 2001 From: akanyan Date: Fri, 9 May 2025 16:07:58 +0000 Subject: [PATCH] feat: add prelaunch scripts --- CHANGELOG.md | 6 ++++++ rust/src/cmd.rs | 6 +++--- rust/src/profiles/mod.rs | 32 ++++++++++++++++++++++++++++++++ rust/src/util.rs | 6 ++++++ rust/tauri.conf.json | 2 +- src/components/FileEditor.vue | 13 ++++++++++--- src/components/options/Misc.vue | 29 +++++++++++++++++++++++++++++ src/i18n/en.ts | 2 ++ src/i18n/pl.ts | 2 ++ 9 files changed, 91 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4996c95..f411464 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.20.0 + +- Added user-customizable pre-launch scripts +- Added japanese localization +- Fixed the file editor not updating state properly + ## 0.19.1 - Fixed the update button enabling the package diff --git a/rust/src/cmd.rs b/rust/src/cmd.rs index 1d93105..982dc52 100644 --- a/rust/src/cmd.rs +++ b/rust/src/cmd.rs @@ -533,14 +533,14 @@ pub async fn clear_cache(state: State<'_, Mutex>) -> Result<(), String> } #[tauri::command] -pub async fn list_platform_capabilities() -> Result, ()> { +pub fn list_platform_capabilities() -> Result, ()> { log::debug!("invoke: list_platform_capabilities"); #[cfg(target_os = "windows")] - return Ok(vec!["display".to_owned(), "shortcut".to_owned(), "chunithm".to_owned()]); + return Ok(vec!["display".to_owned(), "shortcut".to_owned(), "chunithm".to_owned(), "preload-bat".to_owned()]); #[cfg(target_os = "linux")] - return Ok(vec!["wine".to_owned()]); + return Ok(vec!["wine".to_owned(), "preload-sh".to_owned()]); } #[tauri::command] diff --git a/rust/src/profiles/mod.rs b/rust/src/profiles/mod.rs index 209113a..2708ce5 100644 --- a/rust/src/profiles/mod.rs +++ b/rust/src/profiles/mod.rs @@ -255,6 +255,7 @@ impl Profile { let mut game_builder; let mut amd_builder; + let mut prelaunch = None; let target_path = PathBuf::from(&self.data.sgt.target); let exe_dir = target_path.parent().ok_or_else(|| anyhow!("Invalid target path"))?; @@ -264,6 +265,17 @@ impl Profile { { game_builder = Command::new(sgt_dir.join(self.meta.game.inject_exe())); amd_builder = Command::new("cmd.exe"); + + let prelaunch_path = self.config_dir().join("prelaunch.bat"); + if prelaunch_path.exists() { + let mut c = Command::new("cmd"); + c.args(["/C", "start"]); + c.raw_arg("\"STARTLINER Prelaunch\""); + c.args(["cmd", "/C"]); + c.arg(prelaunch_path); + log::debug!("Prelaunch: {:?}", c); + prelaunch = Some(c.spawn()?); + } } #[cfg(target_os = "linux")] { @@ -272,6 +284,14 @@ impl Profile { game_builder.arg(sgt_dir.join(self.meta.game.inject_exe())); amd_builder.arg("cmd.exe"); + + let prelaunch_path = self.config_dir().join("prelaunch.sh"); + if prelaunch_path.exists() { + prelaunch_builder = Some(Command::new("sh")); + c.arg(prelaunch_path); + log::debug!("Prelaunch: {:?}", c); + prelaunch = Some(c.spawn()?); + } } amd_builder.env( @@ -420,6 +440,18 @@ impl Profile { util::pkill("amdaemon.exe").await; } + if let Some(mut _child) = prelaunch { + #[cfg(target_os = "windows")] + { + // child.kill() doesn't work + util::pkill_title("STARTLINER Prelaunch").await; + } + #[cfg(target_os = "linux")] + { + _child.start_kill()?; + } + } + set.join_next().await.expect("No spawn").expect("No result"); log::debug!("Fin"); diff --git a/rust/src/util.rs b/rust/src/util.rs index 3bf9fd2..a3cbfa2 100644 --- a/rust/src/util.rs +++ b/rust/src/util.rs @@ -105,6 +105,12 @@ pub async fn pkill(process_name: &str) { .creation_flags(CREATE_NO_WINDOW).output().await; } +#[cfg(target_os = "windows")] +pub async fn pkill_title(window_title: &str) { + _ = Command::new("taskkill.exe").arg("/fi").raw_arg(format!("\"WindowTitle eq {window_title}\"")) + .creation_flags(CREATE_NO_WINDOW).output().await; +} + #[cfg(target_os = "linux")] pub async fn pkill(process_name: &str) { _ = Command::new("pkill").arg(process_name) diff --git a/rust/tauri.conf.json b/rust/tauri.conf.json index 1250c91..951ef42 100644 --- a/rust/tauri.conf.json +++ b/rust/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "STARTLINER", - "version": "0.19.1", + "version": "0.20.0", "identifier": "zip.patafour.startliner", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/FileEditor.vue b/src/components/FileEditor.vue index f34b20a..d17fa07 100644 --- a/src/components/FileEditor.vue +++ b/src/components/FileEditor.vue @@ -1,5 +1,5 @@ diff --git a/src/i18n/en.ts b/src/i18n/en.ts index efe8a1b..c0af9a7 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -166,6 +166,8 @@ export default { other: 'Other segatools options', otherTooltip: 'Advanced or situational options not covered by STARTLINER', + prelaunch: 'Prelaunch script', + prelaunchTooltip: 'Optional script that runs before the game.', }, extensions: { title: 'Extensions', diff --git a/src/i18n/pl.ts b/src/i18n/pl.ts index 618beeb..00b21d0 100644 --- a/src/i18n/pl.ts +++ b/src/i18n/pl.ts @@ -206,6 +206,8 @@ export default { other: 'Inne opcje segatools', otherTooltip: 'Zaawansowane lub sytuacyjne opcje, które nie są objęte przez STARTLINERA', + prelaunch: 'Skrypt przedstartowy', + prelaunchTooltip: 'Opcjonalny skrypt uruchamiany przed grą.', }, extensions: { title: 'Rozszerzenia',