diff --git a/.gitignore b/.gitignore index ad436745..acbb16c1 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ npm-debug.log.* *.scss.d.ts # externals -externals/bs-admin-start/target/* +externals/**/target/* diff --git a/assets/jsons/bs-versions.json b/assets/jsons/bs-versions.json index 5485247f..8a2b7fdb 100644 --- a/assets/jsons/bs-versions.json +++ b/assets/jsons/bs-versions.json @@ -700,4 +700,4 @@ "ReleaseDate": "1708091473", "year": "2024" } -] +] \ No newline at end of file diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index 6bd2e5ff..72887719 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "Sie müssen Beat Saber mindestens einmal aus dem Oculus Store installiert haben, sonst könnte sich Beat Saber nach dem Start automatisch schließen.", "need-backup": "Um diese Version zu starten, wird der Installationsordner von Beat Saber in Ihrer Oculus-Bibliothek umbenannt.", - "can-restore-later": "Bei Bedarf können Sie ihn vom BSManager aus wiederherstellen, indem Sie zu den Optionen der originalen Oculus-Version gehen und auf 'Ordner wiederherstellen' klicken", - "tips-launch-oculus": "Tipp: Sie können diese Version direkt über Oculus starten, solange die Originalversion nicht wiederhergestellt ist." + "can-restore-later": "Bei Bedarf können Sie ihn vom BSManager aus wiederherstellen, indem Sie zu den Optionen der originalen Oculus-Version gehen und auf 'Ordner wiederherstellen' klicken" }, "not-remind-me": "Nicht mehr erinnern", "understood": "Verstanden" diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 377a4ea7..f615809e 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "You must have installed Beat Saber at least once from the Oculus Store, otherwise Beat Saber might automatically close after launching.", "need-backup": "To launch this version, the Beat Saber installation folder located in your Oculus library will be renamed.", - "can-restore-later": "If needed, you can restore it from BSManager by going to the options of the original Oculus version and clicking on 'Restore the folder'", - "tips-launch-oculus": "Tip: You can launch this version directly from Oculus, as long as the original version is not restored." + "can-restore-later": "If needed, you can restore it from BSManager by going to the options of the original Oculus version and clicking on 'Restore the folder'" }, "not-remind-me": "Do not remind me", "understood": "Understood" diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 418d7bdd..7a5596e4 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "Debes haber instalado Beat Saber al menos una vez desde la Oculus Store, de lo contrario, Beat Saber podría cerrarse automáticamente después de iniciar.", "need-backup": "Para iniciar esta versión, la carpeta de instalación de Beat Saber que se encuentra en tu biblioteca de Oculus será renombrada.", - "can-restore-later": "Si es necesario, podrás restaurarla desde el BSManager accediendo a las opciones de la versión original de Oculus y haciendo clic en 'Restaurar la carpeta'", - "tips-launch-oculus": "Consejo: Podrás iniciar esta versión directamente desde Oculus, siempre que la versión original no haya sido restaurada." + "can-restore-later": "Si es necesario, podrás restaurarla desde el BSManager accediendo a las opciones de la versión original de Oculus y haciendo clic en 'Restaurar la carpeta'" }, "not-remind-me": "No volver a recordármelo", "understood": "Entendido" diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 1840d1d0..a0347710 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "Vous devez avoir installé au moins une fois Beat Saber depuis l'Oculus Store, sinon Beat Saber pourrait se fermer automatiquement après son lancement.", "need-backup": "Pour lancer cette version, le dossier d'installation de Beat Saber se trouvant dans votre librairie Oculus va être renommé.", - "can-restore-later": "Au besoin, vous pourrez le restaurer depuis BSManager en vous rendant dans les options de la version originale Oculus et en cliquant sur \"Restaurer le dossier\"", - "tips-launch-oculus": "Astuce : Vous pourrez lancer cette version directement depuis Oculus, tant que la version originale n'est pas restaurée." + "can-restore-later": "Au besoin, vous pourrez le restaurer depuis BSManager en vous rendant dans les options de la version originale Oculus et en cliquant sur \"Restaurer le dossier\"" }, "not-remind-me": "Ne plus me rappeler", "understood": "J'ai compris" diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 338ac1b5..0c6b9658 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "少なくとも一度はOculus StoreからBeat Saberをインストールしている必要があります。そうしないとBeat Saberは起動後に自動的に終了する可能性があります。", "need-backup": "このバージョンを起動するには、OculusライブラリにあるBeat Saberインストールフォルダの名前を変更します。", - "can-restore-later": "必要であれば、BSManagerから元のOculusバージョンのオプションに行き、'フォルダを復元'をクリックして復元することができます。", - "tips-launch-oculus": "ヒント: 元のバージョンが復元されない限り、Oculusから直接このバージョンを起動することができます。" + "can-restore-later": "必要であれば、BSManagerから元のOculusバージョンのオプションに行き、'フォルダを復元'をクリックして復元することができます。" }, "not-remind-me": "二度と表示しないでください", "understood": "分かった" diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 44d8ef73..8dfb20ee 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "Вы должны были установить Beat Saber хотя бы один раз из Oculus Store, иначе Beat Saber может автоматически закрыться после запуска.", "need-backup": "Для запуска этой версии папка установки Beat Saber в вашей библиотеке Oculus будет переименована.", - "can-restore-later": "При необходимости вы можете восстановить её через BSManager, перейдя в опции оригинальной версии Oculus и нажав на 'Восстановить папку'", - "tips-launch-oculus": "Совет: Вы можете запустить эту версию напрямую через Oculus, пока оригинальная версия не восстановлена." + "can-restore-later": "При необходимости вы можете восстановить её через BSManager, перейдя в опции оригинальной версии Oculus и нажав на 'Восстановить папку'" }, "not-remind-me": "Больше не напоминать", "understood": "Понял" diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index 86543d3b..cf72e52a 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "你必須至少從 Oculus 商店安裝過一次 BeatSaber,否則 BeatSaber 可能會在啟動後自動關閉。", "need-backup": "要啟動該版本,位於你的 Oculus 庫中的 BeatSaber 安裝文件夾將被重命名。", - "can-restore-later": "如果需要,你可以通過前往 BSManager 的原始 Oculus 版本選項並點擊'恢復文件夾'來恢復它。", - "tips-launch-oculus": "提示:只要原始版本沒有被恢復,你就可以直接從 Oculus 啟動該版本。" + "can-restore-later": "如果需要,你可以通過前往 BSManager 的原始 Oculus 版本選項並點擊'恢復文件夾'來恢復它。" }, "not-remind-me": "不再提醒我", "understood": "明白了" diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 057fe18c..98ca3ce6 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -696,8 +696,7 @@ "body": { "must-be-installed-once": "你必须至少从 Oculus 商店安装过一次 BeatSaber,否则 BeatSaber 可能会在启动后自动关闭。", "need-backup": "要启动该版本,位于你的 Oculus 库中的 BeatSaber 安装文件夹将被重命名。", - "can-restore-later": "如果需要,你可以通过前往 BSManager 的原始 Oculus 版本选项并点击'恢复文件夹'来恢复它。", - "tips-launch-oculus": "提示:只要原始版本没有被恢复,你就可以直接从 Oculus 启动该版本。" + "can-restore-later": "如果需要,你可以通过前往 BSManager 的原始 Oculus 版本选项并点击'恢复文件夹'来恢复它。" }, "not-remind-me": "不再提醒我", "understood": "明白了" diff --git a/assets/scripts/oculus_symlink_cleaner.exe b/assets/scripts/oculus_symlink_cleaner.exe new file mode 100644 index 00000000..9abb6862 Binary files /dev/null and b/assets/scripts/oculus_symlink_cleaner.exe differ diff --git a/externals/oculus-symlink-cleaner/.cargo/config.toml b/externals/oculus-symlink-cleaner/.cargo/config.toml new file mode 100644 index 00000000..0c17df09 --- /dev/null +++ b/externals/oculus-symlink-cleaner/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.x86_64-pc-windows-msvc] +rustflags = ["-C", "target-feature=+crt-static"] \ No newline at end of file diff --git a/externals/oculus-symlink-cleaner/Cargo.lock b/externals/oculus-symlink-cleaner/Cargo.lock new file mode 100644 index 00000000..233feb34 --- /dev/null +++ b/externals/oculus-symlink-cleaner/Cargo.lock @@ -0,0 +1,281 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "oculus_symlink_cleaner" +version = "0.1.0" +dependencies = [ + "sysinfo", + "winres", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.30.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] diff --git a/externals/oculus-symlink-cleaner/Cargo.toml b/externals/oculus-symlink-cleaner/Cargo.toml new file mode 100644 index 00000000..f7dcb7e0 --- /dev/null +++ b/externals/oculus-symlink-cleaner/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "oculus_symlink_cleaner" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +winres = "0.1.12" + +[dependencies] +sysinfo = "0.30.6" + +[profile.release] +codegen-units = 1 +lto = true +opt-level = "z" + +[package.metadata.winres] +FileDescription = "Clean Oculus Symlink after Beat Saber ends" +LegalCopyright = "Copyright © 2024 Zagrios" +CompanyName = "Zagrios" diff --git a/externals/oculus-symlink-cleaner/build.rs b/externals/oculus-symlink-cleaner/build.rs new file mode 100644 index 00000000..ac40e20c --- /dev/null +++ b/externals/oculus-symlink-cleaner/build.rs @@ -0,0 +1,9 @@ +extern crate winres; + +fn main() { + if cfg!(target_os = "windows") { + let mut res = winres::WindowsResource::new(); + res.set_icon("./icon.ico"); + res.compile().unwrap(); + } +} diff --git a/externals/oculus-symlink-cleaner/icon.ico b/externals/oculus-symlink-cleaner/icon.ico new file mode 100644 index 00000000..660923e2 Binary files /dev/null and b/externals/oculus-symlink-cleaner/icon.ico differ diff --git a/externals/oculus-symlink-cleaner/src/main.rs b/externals/oculus-symlink-cleaner/src/main.rs new file mode 100644 index 00000000..f7edc5c6 --- /dev/null +++ b/externals/oculus-symlink-cleaner/src/main.rs @@ -0,0 +1,60 @@ +use sysinfo::{Pid, ProcessRefreshKind, System}; +use std::{env, thread, time::Duration, fs}; +use std::ffi::OsStr; +use std::path::Path; +use std::str::FromStr; + +const BEAT_SABER_OCULUS_FOLDER_NAME: &str = "hyperbolic-magnetism-beat-saber"; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() != 3 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let pid: Pid = Pid::from_str(&args[1]).expect("Invalid pid"); + let directory_path = Path::new(&args[2]); + + if directory_path.file_name() != Some(OsStr::new(BEAT_SABER_OCULUS_FOLDER_NAME)) { + eprintln!("Directory name is not {}", BEAT_SABER_OCULUS_FOLDER_NAME); + std::process::exit(1); + } + + // we want to monitor only processes + let mut system = System::new_with_specifics(sysinfo::RefreshKind::new().with_processes(ProcessRefreshKind::everything())); + + loop { + system.refresh_processes(); + let process = system.process(pid); + + match process { + Some(_) => { + println!("Process {} is still running.", pid); + thread::sleep(Duration::from_secs(2)); + }, + None => { + println!("Process {} has stopped, deleting directory {:?}", pid, directory_path); + match delete_dir_if_is_symlink(directory_path) { + Ok(_) => println!("Directory {:?} deleted successfully.", directory_path), + Err(e) => eprintln!("Failed to delete directory {:?}: {}", directory_path, e), + } + break; + } + } + } +} + +fn delete_dir_if_is_symlink(path: &Path) -> Result<(), Box>{ + match path.symlink_metadata()?.file_type().is_symlink() { + true => { + fs::remove_dir_all(path)?; + Ok(()) + }, + false => { + eprintln!("Path {:?} is not a symlink.", path); + Err("Path is not a symlink.".into()) + } + } +} + diff --git a/src/main/services/bs-launcher/abstract-launcher.service.ts b/src/main/services/bs-launcher/abstract-launcher.service.ts index 86c0c0c3..b5827999 100644 --- a/src/main/services/bs-launcher/abstract-launcher.service.ts +++ b/src/main/services/bs-launcher/abstract-launcher.service.ts @@ -5,9 +5,9 @@ import path from "path"; import log from "electron-log"; export abstract class AbstractLauncherService { - + protected readonly localVersions = BSLocalVersionService.getInstance(); - + constructor(){ this.localVersions = BSLocalVersionService.getInstance(); } @@ -46,18 +46,20 @@ export abstract class AbstractLauncherService { } - protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): Promise { - return new Promise((resolve, reject) => { - const bsProcess = this.launchBSProcess(bsExePath, args, options); + protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): {process: ChildProcessWithoutNullStreams, exit: Promise} { + const process = this.launchBSProcess(bsExePath, args, options); - bsProcess.on("error", reject); - bsProcess.on("exit", resolve); - - setTimeout(() => { - bsProcess.removeAllListeners("error"); - bsProcess.removeAllListeners("exit"); - resolve(-1); - }, 30_000); + const exit = new Promise((resolve, reject) => { + process.on("error", (err) => { + log.error(`Error while launching BS`, err); + reject(err); + }); + process.on("exit", (code) => { + log.info(`BS process exit with code ${code}`); + resolve(code); + }); }); + + return { process, exit }; } -} \ No newline at end of file +} diff --git a/src/main/services/bs-launcher/oculus-launcher.service.ts b/src/main/services/bs-launcher/oculus-launcher.service.ts index d6edc3ed..89678809 100644 --- a/src/main/services/bs-launcher/oculus-launcher.service.ts +++ b/src/main/services/bs-launcher/oculus-launcher.service.ts @@ -12,6 +12,9 @@ import { taskRunning } from "../../helpers/os.helpers"; import { CustomError } from "../../../shared/models/exceptions/custom-error.class"; import { InstallationLocationService } from "../installation-location.service"; import { ensurePathNotAlreadyExist } from "../../helpers/fs.helpers"; +import { UtilsService } from "../utils.service"; +import { spawn } from "child_process"; +import { tryit } from "../../../shared/helpers/error.helpers"; export class OculusLauncherService extends AbstractLauncherService implements StoreLauncherInterface { @@ -26,6 +29,7 @@ export class OculusLauncherService extends AbstractLauncherService implements St private readonly oculus: OculusService; private readonly pathsService: InstallationLocationService; + private readonly util: UtilsService; private readonly oculusLib$ = new ReplaySubject(); @@ -33,6 +37,7 @@ export class OculusLauncherService extends AbstractLauncherService implements St super(); this.oculus = OculusService.getInstance(); this.pathsService = InstallationLocationService.getInstance(); + this.util = UtilsService.getInstance(); this.oculus.tryGetGameFolder([OCULUS_BS_DIR, OCULUS_BS_BACKUP_DIR]).then(async dirPath => { if(dirPath){ @@ -100,6 +105,15 @@ export class OculusLauncherService extends AbstractLauncherService implements St return rename(bsFolderBackupPath, originalPath); } + private launchSymlinkCleaner(pid: number, symlinkPath: string){ + + log.info("Launch Symlink Cleaner", pid, symlinkPath); + + const exeName = "oculus_symlink_cleaner.exe"; + const scriptPath = this.util.getAssetsScriptsPath(); + spawn(path.join(scriptPath, exeName), [`${pid}`, symlinkPath], { detached: true, stdio: "ignore" }); + } + public launch(launchOptions: LaunchOption): Observable { const prepareOriginalVersion: () => Promise = async () => { @@ -157,7 +171,16 @@ export class OculusLauncherService extends AbstractLauncherService implements St obs.next({type: BSLaunchEvent.BS_LAUNCHING}); // Launch Beat Saber - return this.launchBs(exePath, this.buildBsLaunchArgs(launchOptions)).catch(err => { + const process = this.launchBs(exePath, this.buildBsLaunchArgs(launchOptions)); + + if(launchOptions.version.oculus !== true && process?.process?.pid){ + const { error } = tryit(() => this.launchSymlinkCleaner(process.process.pid, bsPath)); + if(error){ + log.error("Error while launching symlink cleaner", error); + } + } + + return process.exit.catch(err => { throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR); }); diff --git a/src/main/services/bs-launcher/steam-launcher.service.ts b/src/main/services/bs-launcher/steam-launcher.service.ts index 538993e4..a9d1c76c 100644 --- a/src/main/services/bs-launcher/steam-launcher.service.ts +++ b/src/main/services/bs-launcher/steam-launcher.service.ts @@ -107,7 +107,7 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto obs.next({type: BSLaunchEvent.BS_LAUNCHING}); const launchPromise = !launchOptions.admin ? ( - this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }) + this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }).exit ) : ( new Promise(resolve => { const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} }); diff --git a/src/renderer/components/modal/modal-types/original-oculus-version-backup.modal.tsx b/src/renderer/components/modal/modal-types/original-oculus-version-backup.modal.tsx index d91d939a..a31b3394 100644 --- a/src/renderer/components/modal/modal-types/original-oculus-version-backup.modal.tsx +++ b/src/renderer/components/modal/modal-types/original-oculus-version-backup.modal.tsx @@ -19,11 +19,10 @@ export const OriginalOculusVersionBackupModal: ModalComponent = (

{t("modals.original-version-backup-oculus.title")}

- +

{t("modals.original-version-backup-oculus.body.must-be-installed-once")}

{t("modals.original-version-backup-oculus.body.need-backup")}

{t("modals.original-version-backup-oculus.body.can-restore-later")}

-

{t("modals.original-version-backup-oculus.body.tips-launch-oculus")}