From 0351119d204b16835e7ce42386595049290b4e32 Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Thu, 6 Jun 2024 22:18:23 +0200 Subject: [PATCH 1/2] Parse registry.vdf when looking for Sourcemod directory on Linux --- Cargo.toml | 3 +++ src/helper/linux.rs | 54 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 309b119..4b0ff29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,9 @@ thread-id = "4.2.1" colored = "2.1.0" sentry-log = "0.33.0" +[target.'cfg(target_os = "linux")'.dependencies] +keyvalues-parser = "0.2.0" + [target.'cfg(target_os = "windows")'.dependencies] winconsole = "0.11.1" winreg = "0.52.0" diff --git a/src/helper/linux.rs b/src/helper/linux.rs index 05d2330..ed5e7c9 100644 --- a/src/helper/linux.rs +++ b/src/helper/linux.rs @@ -2,6 +2,7 @@ use log::{debug, error}; use crate::BeansError; use crate::helper::format_directory_path; +use keyvalues_parser::Vdf; /// all possible known directory where steam *might* be /// only is used on linux, since windows will use the registry. @@ -10,6 +11,15 @@ pub const STEAM_POSSIBLE_DIR: &'static [&'static str] = &[ "~/.var/app/com.valvesoftware.Steam/.steam/registry.vdf" ]; +// Registry keys +const REGISTRY_KEYS: [&str; 5] = [ + "HKCU", + "Software", + "Valve", + "Steam", + "SourceModInstallPath" +]; + /// find sourcemod path on linux. /// fetches the fake registry that steam uses from find_steam_reg_path /// and gets the value of Registry/HKCU/Software/Valve/Steam/SourceModInstallPath @@ -29,18 +39,36 @@ pub fn find_sourcemod_path() -> Result } }; - for line in reg_content.lines() { - if line.contains("SourceModInstallPath") - { - let split = &line.split("\"SourceModInstallPath\""); - let last = split.clone() - .last() - .expect("Failed to find SourceModInstallPath") - .trim() - .replace("\"", ""); - return Ok(format_directory_path(last)); - } - } + match Vdf::parse(®_content) + { + Ok(vdf) => { + let mut vdf_obj = vdf.value.get_obj(); + + let mut it = REGISTRY_KEYS.into_iter().peekable(); + while let Some(x) = it.next() { + match vdf_obj { + Some(s) => { + if let Some(elem) = s.get(x) { + if let Some(entry) = elem.last() { + if it.peek().is_none() { + if let Some(sourcemod_path) = entry.get_str() { + return Ok(format_directory_path(sourcemod_path.to_string())); + } + } + else { + vdf_obj = entry.get_obj(); + continue; + } + } + } + }, + None => {}, + } + break; + } + }, + Err(_) => {}, + }; return Err(BeansError::SourceModLocationNotFound); } @@ -73,4 +101,4 @@ fn find_steam_reg_path() -> Result } error!("Couldn't find any of the locations in STEAM_POSSIBLE_DIR"); return Err(BeansError::SteamNotFound); -} \ No newline at end of file +} From 0be2da0438a2f41621b4dc38809607ff4c712443 Mon Sep 17 00:00:00 2001 From: kate Date: Mon, 1 Jul 2024 13:24:53 +0800 Subject: [PATCH 2/2] Add logging when Vdf::parse results in Err --- src/helper/linux.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/helper/linux.rs b/src/helper/linux.rs index ed5e7c9..4dcc3c1 100644 --- a/src/helper/linux.rs +++ b/src/helper/linux.rs @@ -1,5 +1,5 @@ use std::fs::read_to_string; -use log::{debug, error}; +use log::{debug, error, warn, trace}; use crate::BeansError; use crate::helper::format_directory_path; use keyvalues_parser::Vdf; @@ -67,7 +67,10 @@ pub fn find_sourcemod_path() -> Result break; } }, - Err(_) => {}, + Err(e) => { + trace!("{:#?}", e); + warn!("[find_sourcemod_path] failed to parse vdf content {:}", e); + }, }; return Err(BeansError::SourceModLocationNotFound);