fix: locate pressure vessel when installed to non-default location
Some checks are pending
/ cargo-clippy (push) Waiting to run
/ cargo-test (push) Waiting to run
/ cargo-fmtcheck (push) Waiting to run
/ appimage (push) Waiting to run

This commit is contained in:
Sapphire 2024-11-01 11:15:50 +00:00 committed by GabMus
parent b88fc879d2
commit 3f45d2ae4a
4 changed files with 191 additions and 14 deletions

82
Cargo.lock generated
View file

@ -322,6 +322,7 @@ dependencies = [
"gettext-rs",
"git2",
"gtk4",
"keyvalues-serde",
"lazy_static",
"libadwaita",
"libmonado",
@ -1071,6 +1072,28 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "keyvalues-parser"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e4c8354918309196302015ac9cae43362f1a13d0d5c5539a33b4c2fd2cd6d25"
dependencies = [
"pest",
"pest_derive",
"thiserror",
]
[[package]]
name = "keyvalues-serde"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0447866c47c00f8bd1949618e8f63017cf93e985b4684dc28d784527e2882390"
dependencies = [
"keyvalues-parser",
"serde",
"thiserror",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@ -1502,6 +1525,51 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "pest"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]]
name = "pin-project"
version = "1.1.5"
@ -2086,18 +2154,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.48"
version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.48"
version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
dependencies = [
"proc-macro2",
"quote",
@ -2305,6 +2373,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-bidi"
version = "0.3.13"

View file

@ -20,6 +20,7 @@ relm4-components = "0.9.1"
reqwest = { version = "0.12.5", features = ["blocking"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
keyvalues-serde = "0.2.1"
tracker = "0.2.2"
uuid = { version = "1.10.0", features = ["v4", "fast-rng"] }
vte4 = { version = "0.8.0", features = ["v0_72"] }

View file

@ -4,18 +4,76 @@ use crate::{
util::file_utils::{copy_file, get_writer},
};
use anyhow::bail;
use lazy_static::lazy_static;
use serde::Deserialize;
use std::{
collections::HashMap,
fs::read_to_string,
io::Write,
path::{Path, PathBuf},
};
#[derive(Deserialize)]
struct LibraryFolder {
pub path: String,
pub apps: HashMap<u32, usize>,
}
pub const PRESSURE_VESSEL_STEAM_APPID: u32 = 1628350;
fn get_steam_main_dir_path() -> anyhow::Result<PathBuf> {
let steam_root: PathBuf = get_home_dir().join(".steam/root");
if steam_root.is_symlink() {
Ok(steam_root.read_link()?)
} else if steam_root.is_dir() {
Ok(steam_root)
} else {
bail!(
"Canonical steam root '{}' is not a dir nor a symlink!",
steam_root.to_string_lossy()
)
}
}
fn parse_steam_libraryfolders_vdf(path: &Path) -> anyhow::Result<HashMap<u32, LibraryFolder>> {
Ok(keyvalues_serde::from_str(read_to_string(path)?.as_str())?)
}
fn get_runtime_entrypoint_path() -> Option<PathBuf> {
Some(
get_home_dir()
.join(".steam/steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point"),
)
.filter(|p| p.is_file())
match get_steam_main_dir_path() {
Ok(steam_root) => {
let steam_libraryfolders_path = steam_root.join("steamapps/libraryfolders.vdf");
if !steam_libraryfolders_path.is_file() {
eprintln!(
"Steam libraryfolders.vdf does not exist in its canonical location {}",
steam_libraryfolders_path.to_string_lossy()
);
return None;
}
let libraryfolders: HashMap<u32, LibraryFolder> =
parse_steam_libraryfolders_vdf(&steam_libraryfolders_path).ok()?;
libraryfolders
.iter()
.find(|(_, libraryfolder)| {
libraryfolder
.apps
.contains_key(&PRESSURE_VESSEL_STEAM_APPID)
})
.map(|(_, libraryfolder)| PathBuf::from(&libraryfolder.path))
}
Err(e) => {
eprintln!("Error getting steam root path: {e}");
None
}
}
}
lazy_static! {
static ref STEAM_RUNTIME_ENTRYPOINT_PATH: Option<PathBuf> = get_runtime_entrypoint_path();
}
fn get_backup_runtime_entrypoint_location() -> PathBuf {
@ -27,10 +85,10 @@ fn backup_runtime_entrypoint(path: &Path) {
}
pub fn restore_runtime_entrypoint() {
if let Some(path) = get_runtime_entrypoint_path() {
if let Some(path) = STEAM_RUNTIME_ENTRYPOINT_PATH.as_ref() {
let backup = get_backup_runtime_entrypoint_location();
if Path::new(&backup).is_file() {
copy_file(&backup, &path);
copy_file(&backup, path);
}
}
}
@ -48,8 +106,8 @@ fn append_to_runtime_entrypoint(data: &str, path: &Path) -> anyhow::Result<()> {
pub fn set_runtime_entrypoint_launch_opts_from_profile(profile: &Profile) -> anyhow::Result<()> {
restore_runtime_entrypoint();
if let Some(dest) = get_runtime_entrypoint_path() {
backup_runtime_entrypoint(&dest);
if let Some(dest) = STEAM_RUNTIME_ENTRYPOINT_PATH.as_ref() {
backup_runtime_entrypoint(dest);
append_to_runtime_entrypoint(
&profile
.get_env_vars()
@ -57,10 +115,29 @@ pub fn set_runtime_entrypoint_launch_opts_from_profile(profile: &Profile) -> any
.map(|ev| "export ".to_string() + ev)
.collect::<Vec<String>>()
.join("\n"),
&dest,
dest,
)?;
return Ok(());
}
bail!("Could not find valid runtime entrypoint");
}
#[cfg(test)]
mod tests {
use std::path::Path;
use super::parse_steam_libraryfolders_vdf;
#[test]
fn deserialize_steam_libraryfolders_vdf() {
let lf = parse_steam_libraryfolders_vdf(Path::new("./test/files/steam_libraryfolders.vdf"))
.unwrap();
assert_eq!(lf.len(), 1);
let first = lf.get(&0).unwrap();
assert_eq!(first.path, "/home/gabmus/.local/share/Steam");
assert_eq!(first.apps.len(), 10);
assert_eq!(first.apps.get(&228980).unwrap(), &29212173);
assert_eq!(first.apps.get(&632360).unwrap(), &0);
}
}

View file

@ -0,0 +1,25 @@
"libraryfolders"
{
"0"
{
"path" "/home/gabmus/.local/share/Steam"
"label" ""
"contentid" "760750217583951648"
"totalsize" "0"
"update_clean_bytes_tally" "2149063455"
"time_last_update_verified" "1730413202"
"apps"
{
"228980" "29212173"
"427520" "1827889703"
"632360" "0"
"844590" "1141373655"
"1070560" "13004"
"1391110" "647029573"
"1493710" "1222765697"
"1628350" "768814815"
"2124120" "1434049913"
"2537200" "1681670599"
}
}
}