70 lines
2 KiB
Rust
70 lines
2 KiB
Rust
use std::{fmt, ops::Deref, path::PathBuf};
|
|
|
|
#[derive(Debug)]
|
|
pub struct HeuristicError {
|
|
message: String,
|
|
}
|
|
|
|
impl fmt::Display for HeuristicError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", &self.message)
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for HeuristicError {}
|
|
|
|
impl HeuristicError {
|
|
fn new<S: AsRef<str>>(mesg: S) -> Self {
|
|
Self {
|
|
message: mesg.as_ref().to_owned(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Gets the Steam local directory
|
|
pub fn get_steamdir() -> Result<PathBuf, Box<dyn std::error::Error>> {
|
|
let mut dir = dirs::data_local_dir().unwrap_or_else(|| {
|
|
let mut dir = dirs::home_dir().unwrap();
|
|
dir.push(".local/share");
|
|
dir
|
|
});
|
|
dir.push("Steam");
|
|
Ok(dir)
|
|
}
|
|
|
|
/// Attempt to get the userdata dir via loginusers.vdf
|
|
pub fn get_userdir() -> Result<PathBuf, Box<dyn std::error::Error>> {
|
|
let steam_dir = get_steamdir()?;
|
|
|
|
let users_path = {
|
|
let mut dir = steam_dir.clone();
|
|
dir.push("config/loginusers.vdf");
|
|
dir
|
|
};
|
|
if let steamy_vdf::Entry::Table(table) = steamy_vdf::load(users_path)? {
|
|
if let steamy_vdf::Entry::Table(users) = &table["users"] {
|
|
let mut last_id: Option<u64> = None;
|
|
for (uid, data) in users.iter() {
|
|
let data = data.as_table().unwrap();
|
|
if let Some(steamy_vdf::Entry::Value(most_recent)) = data.get("MostRecent") {
|
|
if most_recent.deref() == "1" {
|
|
last_id = Some(uid.parse()?);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if let Some(last_id) = last_id {
|
|
let mut userdir = steam_dir;
|
|
userdir.push(format!("userdata/{}", last_id & 0xffffffff));
|
|
return Ok(userdir);
|
|
}
|
|
}
|
|
} else {
|
|
return Err(HeuristicError::new(
|
|
"steamy_vdf::load gave us something other than Table ???",
|
|
))?;
|
|
}
|
|
|
|
Err(HeuristicError::new("Couldn't guess your user ID"))?
|
|
}
|