diff --git a/.gitignore b/.gitignore
index da134307..ad436745 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,6 @@ npm-debug.log.*
*.css.d.ts
*.sass.d.ts
*.scss.d.ts
+
+# externals
+externals/bs-admin-start/target/*
diff --git a/assets/scripts/start_beat_saber_admin.exe b/assets/scripts/start_beat_saber_admin.exe
new file mode 100644
index 00000000..672a78e8
Binary files /dev/null and b/assets/scripts/start_beat_saber_admin.exe differ
diff --git a/externals/bs-admin-start/.cargo/config.toml b/externals/bs-admin-start/.cargo/config.toml
new file mode 100644
index 00000000..ac2b23f8
--- /dev/null
+++ b/externals/bs-admin-start/.cargo/config.toml
@@ -0,0 +1,2 @@
+[target.x86_64-pc-windows-msvc]
+rustflags = ["-C", "target-feature=+crt-static"]
diff --git a/externals/bs-admin-start/Cargo.lock b/externals/bs-admin-start/Cargo.lock
new file mode 100644
index 00000000..f15d8279
--- /dev/null
+++ b/externals/bs-admin-start/Cargo.lock
@@ -0,0 +1,83 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
+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 = "serde"
+version = "1.0.195"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.195"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "start_beat_saber_admin"
+version = "0.1.0"
+dependencies = [
+ "winres",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[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 = "winres"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
+dependencies = [
+ "toml",
+]
diff --git a/externals/bs-admin-start/Cargo.toml b/externals/bs-admin-start/Cargo.toml
new file mode 100644
index 00000000..118f1b32
--- /dev/null
+++ b/externals/bs-admin-start/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "start_beat_saber_admin"
+version = "0.1.0"
+edition = "2021"
+build = "build.rs"
+
+[build-dependencies]
+winres = "0.1.12"
+
+[profile.release]
+codegen-units = 1
+lto = true
+opt-level = "z"
+
+[package.metadata.winres]
+FileDescription = "Start Beat Saber as Admin"
+LegalCopyright = "Copyright © 2024 Zagrios"
+CompanyName = "Zagrios"
diff --git a/externals/bs-admin-start/build.rs b/externals/bs-admin-start/build.rs
new file mode 100644
index 00000000..374f1355
--- /dev/null
+++ b/externals/bs-admin-start/build.rs
@@ -0,0 +1,20 @@
+extern crate winres;
+
+fn main() {
+ if cfg!(target_os = "windows") {
+ let mut res = winres::WindowsResource::new();
+ res.set_manifest(r#"
+
+
+
+
+
+
+
+
+
+ "#);
+ res.set_icon("./icon.ico");
+ res.compile().unwrap();
+ }
+}
diff --git a/externals/bs-admin-start/icon.ico b/externals/bs-admin-start/icon.ico
new file mode 100644
index 00000000..660923e2
Binary files /dev/null and b/externals/bs-admin-start/icon.ico differ
diff --git a/externals/bs-admin-start/src/main.rs b/externals/bs-admin-start/src/main.rs
new file mode 100644
index 00000000..18b1dbb5
--- /dev/null
+++ b/externals/bs-admin-start/src/main.rs
@@ -0,0 +1,17 @@
+
+use std::{process::Command, path::Path};
+
+fn main() {
+ let args: Vec = std::env::args().collect();
+
+ let mut command = Command::new(args.get(1).unwrap());
+ command.current_dir(Path::new(args.get(1).unwrap()).parent().unwrap());
+
+ for arg in args.iter().skip(1) {
+ command.arg(arg);
+ }
+
+ command.env("SteamAppId", "620980");
+
+ let _ = command.spawn();
+}
diff --git a/package-lock.json b/package-lock.json
index 8fda678d..0305a3a8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,7 @@
"framer-motion": "^10.16.16",
"fs-extra": "^11.2.0",
"history": "^5.3.0",
+ "is-elevated": "^3.0.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.47.0",
@@ -7047,7 +7048,6 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
"dependencies": {
"once": "^1.4.0"
}
@@ -10291,6 +10291,125 @@
"node": ">= 10"
}
},
+ "node_modules/is-admin": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-admin/-/is-admin-3.0.0.tgz",
+ "integrity": "sha512-wOa3CXFJAu8BZ2BDtG9xYOOrsq6oiSvc2jFPy4X/HINx5bmJUcW8e+apItVbU2E7GIfBVaFVO7Zit4oAWtTJcw==",
+ "dependencies": {
+ "execa": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-admin/node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/is-admin/node_modules/execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-admin/node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-admin/node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-admin/node_modules/npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dependencies": {
+ "path-key": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-admin/node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-admin/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/is-admin/node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-admin/node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-admin/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -10431,6 +10550,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-elevated": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-elevated/-/is-elevated-3.0.0.tgz",
+ "integrity": "sha512-wjcp6RkouU9jpg55zERl+BglvV5j4jx5c/EMvQ+d12j/+nIEenNWPu+qc0tCg3JkLodbKZMg1qhJzEwG4qjclg==",
+ "dependencies": {
+ "is-admin": "^3.0.0",
+ "is-root": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -10595,6 +10726,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-root": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
+ "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/is-set": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
@@ -10760,8 +10899,7 @@
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"node_modules/isobject": {
"version": "3.0.1",
@@ -13572,6 +13710,11 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -14080,6 +14223,14 @@
"node": ">=8"
}
},
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -15389,7 +15540,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -16629,8 +16779,7 @@
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
@@ -17091,6 +17240,14 @@
"node": ">=4"
}
},
+ "node_modules/strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
@@ -24610,7 +24767,6 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
"requires": {
"once": "^1.4.0"
}
@@ -26978,6 +27134,94 @@
"integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==",
"dev": true
},
+ "is-admin": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-admin/-/is-admin-3.0.0.tgz",
+ "integrity": "sha512-wOa3CXFJAu8BZ2BDtG9xYOOrsq6oiSvc2jFPy4X/HINx5bmJUcW8e+apItVbU2E7GIfBVaFVO7Zit4oAWtTJcw==",
+ "requires": {
+ "execa": "^1.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
+ },
+ "semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -27073,6 +27317,15 @@
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true
},
+ "is-elevated": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-elevated/-/is-elevated-3.0.0.tgz",
+ "integrity": "sha512-wjcp6RkouU9jpg55zERl+BglvV5j4jx5c/EMvQ+d12j/+nIEenNWPu+qc0tCg3JkLodbKZMg1qhJzEwG4qjclg==",
+ "requires": {
+ "is-admin": "^3.0.0",
+ "is-root": "^2.1.0"
+ }
+ },
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -27183,6 +27436,11 @@
"has-tostringtag": "^1.0.0"
}
},
+ "is-root": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
+ "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg=="
+ },
"is-set": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
@@ -27294,8 +27552,7 @@
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"isobject": {
"version": "3.0.1",
@@ -29583,6 +29840,11 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
"no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -29954,6 +30216,11 @@
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
"dev": true
},
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="
+ },
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -30844,7 +31111,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -31787,8 +32053,7 @@
"signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"simple-swizzle": {
"version": "0.2.2",
@@ -32152,6 +32417,11 @@
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true
},
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q=="
+ },
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
diff --git a/package.json b/package.json
index 3e8e3c40..24abeafb 100644
--- a/package.json
+++ b/package.json
@@ -250,6 +250,7 @@
"framer-motion": "^10.16.16",
"fs-extra": "^11.2.0",
"history": "^5.3.0",
+ "is-elevated": "^3.0.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.47.0",
diff --git a/release/app/package-lock.json b/release/app/package-lock.json
index 20438518..94f8f59f 100644
--- a/release/app/package-lock.json
+++ b/release/app/package-lock.json
@@ -11,6 +11,7 @@
"license": "MIT",
"dependencies": {
"ps-list": "^7.2.0",
+ "query-process": "^0.0.3",
"regedit-rs": "^1.0.2",
"sharp": "^0.32.6"
}
@@ -344,6 +345,160 @@
"once": "^1.3.1"
}
},
+ "node_modules/query-process": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process/-/query-process-0.0.3.tgz",
+ "integrity": "sha512-6WRue0P+c84abP0o8MkDvigoS/gkkJzsSBt10PsOoBkP7Yodo4DducFsn9XyS4S+LuVYPAE5Hr4+kVNR5Onykg==",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "query-process-android-arm-eabi": "0.0.3",
+ "query-process-android-arm64": "0.0.3",
+ "query-process-linux-arm-gnueabihf": "0.0.3",
+ "query-process-linux-arm64-gnu": "0.0.3",
+ "query-process-linux-arm64-musl": "0.0.3",
+ "query-process-linux-x64-gnu": "0.0.3",
+ "query-process-linux-x64-musl": "0.0.3",
+ "query-process-win32-arm64-msvc": "0.0.3",
+ "query-process-win32-x64-msvc": "0.0.3"
+ }
+ },
+ "node_modules/query-process-android-arm-eabi": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-android-arm-eabi/-/query-process-android-arm-eabi-0.0.3.tgz",
+ "integrity": "sha512-NB+9T+/poBcygDiG+7d2lJSeioP5ZyLT0HwUBdnLgNWvNCpzbJxydup1SLpnt5G2NF6nlTgbUZlH4hvxY7t/bw==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-android-arm64": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-android-arm64/-/query-process-android-arm64-0.0.3.tgz",
+ "integrity": "sha512-TiAw2yO62vQzM0s02471LToHyUs/PRkLGGlA715z10BPIM5NckzIe245AI45CDyH6tE/3nVHUd0LX/dfjQtTcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-linux-arm-gnueabihf": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm-gnueabihf/-/query-process-linux-arm-gnueabihf-0.0.3.tgz",
+ "integrity": "sha512-w7NLHBKt7qselCDoh/PVWyeuEb2NiiDDf1A9UB4K3Ns/H24hK3NbfMMBm8mCFxUnFUqoVX8O+VMs7dD/FNlTxA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-linux-arm64-gnu": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm64-gnu/-/query-process-linux-arm64-gnu-0.0.3.tgz",
+ "integrity": "sha512-nrPHjnSqCBuuN7IZkZWOnBpiJjyKOjfpT0Xt2EjSGp+I7C0CHbnhCL/vG1hBzaWZn0mxJ5nf0c5N0Fja7krnpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-linux-arm64-musl": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm64-musl/-/query-process-linux-arm64-musl-0.0.3.tgz",
+ "integrity": "sha512-vk8xMYTnS1PRKhwJgqLKyBAGIFP2CYZW2BsaKuNgQKUrDv7NnBaG7yukZT8niHNO1ycSrFpR/xqeJ8R23hO07A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-linux-x64-gnu": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-x64-gnu/-/query-process-linux-x64-gnu-0.0.3.tgz",
+ "integrity": "sha512-j1tGcNnGyVCABJ1PHZD1gKuyuomNzsPow3NDuZzUGjPqvKu67RsmKJJJOhMyT1SvUkcqdLFdtS1KTD20I4GS5Q==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-linux-x64-musl": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-x64-musl/-/query-process-linux-x64-musl-0.0.3.tgz",
+ "integrity": "sha512-AOGrrI/Qcb30iKFstiW60zNG/HQevCY0Q38eMHGd7LrBZ5sEN7NzZOjzKp43KeNHejuZBDMxf0gdGAqDznOAng==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-win32-arm64-msvc": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-win32-arm64-msvc/-/query-process-win32-arm64-msvc-0.0.3.tgz",
+ "integrity": "sha512-LHvxbzMFwPPUXHe4bDCAqs1bYbp8j0bMW8XyJGPZnIYrnwHz6g8VE5WQEtXQxSznsbfVxAKJXUtn088EjDVazw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/query-process-win32-x64-msvc": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-win32-x64-msvc/-/query-process-win32-x64-msvc-0.0.3.tgz",
+ "integrity": "sha512-LfHAKmfqyKCgl9K+sTz0KyNwMwB79VcXZUy/Et9iQKLuZt7PDYpHWcFdhrfHw2qqIdKWTED8KmnmsOLhUn/2OA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/queue-tick": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
@@ -851,6 +1006,76 @@
"once": "^1.3.1"
}
},
+ "query-process": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process/-/query-process-0.0.3.tgz",
+ "integrity": "sha512-6WRue0P+c84abP0o8MkDvigoS/gkkJzsSBt10PsOoBkP7Yodo4DducFsn9XyS4S+LuVYPAE5Hr4+kVNR5Onykg==",
+ "requires": {
+ "query-process-android-arm-eabi": "0.0.3",
+ "query-process-android-arm64": "0.0.3",
+ "query-process-linux-arm-gnueabihf": "0.0.3",
+ "query-process-linux-arm64-gnu": "0.0.3",
+ "query-process-linux-arm64-musl": "0.0.3",
+ "query-process-linux-x64-gnu": "0.0.3",
+ "query-process-linux-x64-musl": "0.0.3",
+ "query-process-win32-arm64-msvc": "0.0.3",
+ "query-process-win32-x64-msvc": "0.0.3"
+ }
+ },
+ "query-process-android-arm-eabi": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-android-arm-eabi/-/query-process-android-arm-eabi-0.0.3.tgz",
+ "integrity": "sha512-NB+9T+/poBcygDiG+7d2lJSeioP5ZyLT0HwUBdnLgNWvNCpzbJxydup1SLpnt5G2NF6nlTgbUZlH4hvxY7t/bw==",
+ "optional": true
+ },
+ "query-process-android-arm64": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-android-arm64/-/query-process-android-arm64-0.0.3.tgz",
+ "integrity": "sha512-TiAw2yO62vQzM0s02471LToHyUs/PRkLGGlA715z10BPIM5NckzIe245AI45CDyH6tE/3nVHUd0LX/dfjQtTcw==",
+ "optional": true
+ },
+ "query-process-linux-arm-gnueabihf": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm-gnueabihf/-/query-process-linux-arm-gnueabihf-0.0.3.tgz",
+ "integrity": "sha512-w7NLHBKt7qselCDoh/PVWyeuEb2NiiDDf1A9UB4K3Ns/H24hK3NbfMMBm8mCFxUnFUqoVX8O+VMs7dD/FNlTxA==",
+ "optional": true
+ },
+ "query-process-linux-arm64-gnu": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm64-gnu/-/query-process-linux-arm64-gnu-0.0.3.tgz",
+ "integrity": "sha512-nrPHjnSqCBuuN7IZkZWOnBpiJjyKOjfpT0Xt2EjSGp+I7C0CHbnhCL/vG1hBzaWZn0mxJ5nf0c5N0Fja7krnpQ==",
+ "optional": true
+ },
+ "query-process-linux-arm64-musl": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-arm64-musl/-/query-process-linux-arm64-musl-0.0.3.tgz",
+ "integrity": "sha512-vk8xMYTnS1PRKhwJgqLKyBAGIFP2CYZW2BsaKuNgQKUrDv7NnBaG7yukZT8niHNO1ycSrFpR/xqeJ8R23hO07A==",
+ "optional": true
+ },
+ "query-process-linux-x64-gnu": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-x64-gnu/-/query-process-linux-x64-gnu-0.0.3.tgz",
+ "integrity": "sha512-j1tGcNnGyVCABJ1PHZD1gKuyuomNzsPow3NDuZzUGjPqvKu67RsmKJJJOhMyT1SvUkcqdLFdtS1KTD20I4GS5Q==",
+ "optional": true
+ },
+ "query-process-linux-x64-musl": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-linux-x64-musl/-/query-process-linux-x64-musl-0.0.3.tgz",
+ "integrity": "sha512-AOGrrI/Qcb30iKFstiW60zNG/HQevCY0Q38eMHGd7LrBZ5sEN7NzZOjzKp43KeNHejuZBDMxf0gdGAqDznOAng==",
+ "optional": true
+ },
+ "query-process-win32-arm64-msvc": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-win32-arm64-msvc/-/query-process-win32-arm64-msvc-0.0.3.tgz",
+ "integrity": "sha512-LHvxbzMFwPPUXHe4bDCAqs1bYbp8j0bMW8XyJGPZnIYrnwHz6g8VE5WQEtXQxSznsbfVxAKJXUtn088EjDVazw==",
+ "optional": true
+ },
+ "query-process-win32-x64-msvc": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/query-process-win32-x64-msvc/-/query-process-win32-x64-msvc-0.0.3.tgz",
+ "integrity": "sha512-LfHAKmfqyKCgl9K+sTz0KyNwMwB79VcXZUy/Et9iQKLuZt7PDYpHWcFdhrfHw2qqIdKWTED8KmnmsOLhUn/2OA==",
+ "optional": true
+ },
"queue-tick": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
diff --git a/release/app/package.json b/release/app/package.json
index 2f41eb68..ffb87505 100644
--- a/release/app/package.json
+++ b/release/app/package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"ps-list": "^7.2.0",
+ "query-process": "^0.0.3",
"regedit-rs": "^1.0.2",
"sharp": "^0.32.6"
},
diff --git a/src/main/helpers/os.helpers.ts b/src/main/helpers/os.helpers.ts
index da6aed8d..e44a6c70 100644
--- a/src/main/helpers/os.helpers.ts
+++ b/src/main/helpers/os.helpers.ts
@@ -10,4 +10,16 @@ export async function taskRunning(task: string): Promise {
log.error(error);
return false;
}
-}
\ No newline at end of file
+}
+
+export async function getProcessPid(task: string): Promise {
+ try {
+ const processes = await psList();
+ const process = processes.find(process => process.name?.includes(task) || process.cmd?.includes(task));
+ return process?.pid;
+ }
+ catch(error){
+ log.error(error);
+ return null;
+ }
+}
diff --git a/src/main/services/bs-launcher/steam-launcher.service.ts b/src/main/services/bs-launcher/steam-launcher.service.ts
index 7ebc0cb0..29e6d861 100644
--- a/src/main/services/bs-launcher/steam-launcher.service.ts
+++ b/src/main/services/bs-launcher/steam-launcher.service.ts
@@ -8,6 +8,9 @@ import { BS_APP_ID, BS_EXECUTABLE, STEAMVR_APP_ID } from "../../constants";
import log from "electron-log";
import { AbstractLauncherService } from "./abstract-launcher.service";
import { CustomError } from "../../../shared/models/exceptions/custom-error.class";
+import isElevated from "is-elevated";
+import { UtilsService } from "../utils.service";
+import { exec } from "child_process";
export class SteamLauncherService extends AbstractLauncherService implements StoreLauncherInterface{
@@ -21,10 +24,12 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
}
private readonly steam: SteamService;
+ private readonly util: UtilsService;
private constructor(){
super();
this.steam = SteamService.getInstance();
+ this.util = UtilsService.getInstance();
}
private getSteamVRPath(): Promise {
@@ -41,6 +46,17 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
});
}
+ private needStartBsAsAdmin(): Promise {
+ return isElevated().then(elevated => {
+ if(elevated){ return false; }
+ return this.steam.isElevated();
+ })
+ }
+
+ private getStartBsAsAdminExePath(): string {
+ return path.join(this.util.getAssetsScriptsPath(), "start_beat_saber_admin.exe");
+ }
+
public async restoreSteamVR(): Promise {
const steamVrFolder = await this.getSteamVRPath();
const steamVrBackup = `${steamVrFolder}.bak`;
@@ -53,7 +69,7 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
log.error("Error while restoring SteamVR", err);
});
}
-
+
public launch(launchOptions: LaunchOption): Observable{
return new Observable(obs => {(async () => {
@@ -90,7 +106,26 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
obs.next({type: BSLaunchEvent.BS_LAUNCHING});
- await this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }).then(exitCode => {
+ const needToStartAsAdmin = await this.needStartBsAsAdmin().catch(err => {
+ log.error("Error while checking if need to start BS as Admin", err);
+ return false;
+ });
+
+ const launchPromise = !needToStartAsAdmin ? (
+ this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} })
+ ) : (
+ new Promise(resolve => {
+ const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} });
+ adminProcess.on("error", err => {log.error("Error while starting BS as Admin", err); resolve(-1)});
+
+ setTimeout(() => {
+ adminProcess.removeAllListeners("error");
+ resolve(-1);
+ }, 35_000);
+ })
+ );
+
+ await launchPromise.then(exitCode => {
log.info("BS process exit code", exitCode);
}).catch(err => {
throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR);
@@ -109,4 +144,4 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
})});
}
-}
\ No newline at end of file
+}
diff --git a/src/main/services/steam.service.ts b/src/main/services/steam.service.ts
index 9e8472a3..5583169d 100644
--- a/src/main/services/steam.service.ts
+++ b/src/main/services/steam.service.ts
@@ -5,11 +5,15 @@ import { readFile } from "fs/promises";
import { pathExist } from "../helpers/fs.helpers";
import log from "electron-log";
import { app, shell } from "electron";
-import { taskRunning } from "../helpers/os.helpers";
+import { getProcessPid, taskRunning } from "../helpers/os.helpers";
+import { isElevated } from "query-process";
export class SteamService {
+ private static readonly PROCESS_NAME = "steam";
+
private static instance: SteamService;
+
private steamPath: string = '';
private constructor(){}
@@ -29,12 +33,25 @@ export class SteamService {
}
public async steamRunning(): Promise{
- const steamProcessRunning = await taskRunning("steam");
+ const steamProcessRunning = await taskRunning(SteamService.PROCESS_NAME);
if(process.platform === "linux") { return steamProcessRunning; }
const activeUser = await this.getActiveUser().catch(err => log.error(err));
return steamProcessRunning && !!activeUser;
}
+ public async getSteamPid(): Promise{
+ return getProcessPid(SteamService.PROCESS_NAME);
+ }
+
+ public async isElevated(): Promise{
+ if(process.platform === "linux"){ return true; }
+ const steamPid = await this.getSteamPid();
+
+ if(!steamPid){ return false; }
+
+ return isElevated(steamPid);
+ }
+
public async getSteamPath(): Promise{
if(this.steamPath){ return this.steamPath; }
@@ -68,7 +85,7 @@ export class SteamService {
let libraryFolders: any = path.join(steamPath, "steamapps", "libraryfolders.vdf");
if (!(await pathExist(libraryFolders))) { return null; }
-
+
libraryFolders = parse(await readFile(libraryFolders, { encoding: "utf-8" }));
if (!libraryFolders.libraryfolders) { return null; }
@@ -83,7 +100,7 @@ export class SteamService {
}
return null;
-
+
} catch (e) {
log.error(e);
return null;
@@ -91,7 +108,7 @@ export class SteamService {
}
public async openSteam(): Promise {
-
+
await shell.openPath("steam://open/games");
return new Promise((resolve, reject) => {