[bugfix] Added a Beat Saber ends watcher to delete created symlink to avoid Oculus version getting wiped by Oculus auto updates

This commit is contained in:
MathieuG-P
2024-03-05 13:33:04 +01:00
parent 6b30d74628
commit 2d67876ee1
21 changed files with 426 additions and 36 deletions
+1 -1
View File
@@ -29,4 +29,4 @@ npm-debug.log.*
*.scss.d.ts
# externals
externals/bs-admin-start/target/*
externals/**/target/*
+1 -1
View File
@@ -700,4 +700,4 @@
"ReleaseDate": "1708091473",
"year": "2024"
}
]
]
+1 -2
View File
@@ -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"
+1 -2
View File
@@ -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"
+1 -2
View File
@@ -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"
+1 -2
View File
@@ -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"
+1 -2
View File
@@ -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": "分かった"
+1 -2
View File
@@ -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": "Понял"
+1 -2
View File
@@ -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": "明白了"
+1 -2
View File
@@ -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": "明白了"
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
+281
View File
@@ -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",
]
+22
View File
@@ -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"
+9
View File
@@ -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();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

+60
View File
@@ -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<String> = env::args().collect();
if args.len() != 3 {
eprintln!("Usage: {} <pid> <path_to_directory>", 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<dyn std::error::Error>>{
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())
}
}
}
@@ -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<number> {
return new Promise<number>((resolve, reject) => {
const bsProcess = this.launchBSProcess(bsExePath, args, options);
protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): {process: ChildProcessWithoutNullStreams, exit: Promise<number>} {
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<number>((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 };
}
}
}
@@ -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<string>();
@@ -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<BSLaunchEventData> {
const prepareOriginalVersion: () => Promise<string> = 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);
});
@@ -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<number>(resolve => {
const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} });
@@ -19,11 +19,10 @@ export const OriginalOculusVersionBackupModal: ModalComponent<boolean, void> = (
<form className="max-w-[450px] text-gray-800 dark:text-gray-200">
<h1 className="text-3xl uppercase tracking-wide w-full text-center text-gray-800 dark:text-gray-200">{t("modals.original-version-backup-oculus.title")}</h1>
<BsmImage className="mx-auto h-20" image={BeatConflict} />
<p className="text-sm italic mb-4 font-bold">{t("modals.original-version-backup-oculus.body.must-be-installed-once")}</p>
<p className="mb-4">{t("modals.original-version-backup-oculus.body.need-backup")}</p>
<p className="mb-4">{t("modals.original-version-backup-oculus.body.can-restore-later")}</p>
<p className="text-sm italic mb-4">{t("modals.original-version-backup-oculus.body.tips-launch-oculus")}</p>
<div className="flex flex-row justify-start items-center gap-1.5 my-4" >
<BsmCheckbox className="relative z-[1] w-6 aspect-square" checked={dontShowAgain} onChange={setDontShowAgain} />