wormhole_common/finder/
steam.rs1use std::{fs, path::PathBuf};
2
3use keyvalues_parser::Vdf;
4
5#[cfg(target_os = "linux")]
6use super::resolver::linux;
7#[cfg(target_os = "macos")]
8use super::resolver::macos;
9#[cfg(target_os = "windows")]
10use super::resolver::windows;
11
12#[derive(Default, Clone, Debug)]
13pub struct LibraryFolders {
14 pub paths: Vec<PathBuf>,
15 pub discovered: bool,
16}
17
18impl LibraryFolders {
19 pub fn new() -> Self {
20 return Self {
21 paths: vec![],
22 discovered: false,
23 };
24 }
25
26 #[cfg(target_os = "macos")]
27 pub fn get_library_folders_file(&self) -> PathBuf {
28 return macos::get_steam_library_folders_file();
29 }
30
31 #[cfg(target_os = "linux")]
32 pub fn get_library_folders_file(&self) -> PathBuf {
33 return linux::get_steam_library_folders_file();
34 }
35
36 #[cfg(target_os = "windows")]
37 pub fn get_library_folders_file(&self) -> PathBuf {
38 return windows::get_steam_library_folders_file();
39 }
40
41 pub fn discover(&mut self) -> Option<&mut Self> {
42 let libraryfolders_vdf_path = self.get_library_folders_file();
43
44 if libraryfolders_vdf_path.is_file() {
45 let vdf_text = fs::read_to_string(&libraryfolders_vdf_path).ok()?;
46 let value = Vdf::parse(&vdf_text).ok()?.value;
47 let obj = value.get_obj()?;
48
49 let library_folders: Vec<_> = obj
50 .iter()
51 .filter(|(key, values)| key.parse::<u32>().is_ok() && values.len() == 1)
52 .filter_map(|(_, values)| {
53 let library_folder_string = values
54 .get(0)?
55 .get_obj()?
56 .get("path")?
57 .get(0)?
58 .get_str()?
59 .to_string();
60
61 let library_folder = PathBuf::from(library_folder_string).join("steamapps");
62
63 return Some(library_folder);
64 })
65 .collect();
66
67 self.paths = library_folders;
68 }
69
70 self.discovered = true;
71
72 return Some(self);
73 }
74}
75
76pub struct SteamInstallFinder {
77 pub library_folders: LibraryFolders,
78}
79
80impl Default for SteamInstallFinder {
81 fn default() -> Self {
82 let mut me = Self {
83 library_folders: LibraryFolders::new(),
84 };
85
86 me.library_folders
87 .discover()
88 .expect("Failed to discover Steam library folders!");
89
90 return me;
91 }
92}
93
94impl SteamInstallFinder {
95 pub fn find_ksp2_dir(&mut self) -> Option<PathBuf> {
96 for library_folder in self.library_folders.clone().paths {
97 let ksp2_dir = library_folder.join("common").join("Kerbal Space Program 2");
98
99 if ksp2_dir.is_dir() {
100 let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten();
101
102 for file in dir_contents {
103 let file_path = file.path();
104
105 if file_path.is_file()
106 && file_path
107 .as_os_str()
108 .to_str()
109 .unwrap()
110 .contains("KSP2_x64.exe")
111 {
112 return Some(ksp2_dir);
113 }
114 }
115 }
116 }
117
118 return None;
119 }
120
121 pub fn find_ksp1_dir(&mut self) -> Option<PathBuf> {
122 for library_folder in self.library_folders.clone().paths {
123 let ksp2_dir = library_folder.join("common").join("Kerbal Space Program");
124
125 if ksp2_dir.is_dir() {
126 let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten();
127
128 for file in dir_contents {
129 let file_path = file.path();
130
131 if file_path.is_file()
132 && file_path
133 .as_os_str()
134 .to_str()
135 .unwrap()
136 .contains("KSP_x64.exe")
137 {
138 return Some(ksp2_dir);
139 }
140 }
141 }
142 }
143
144 return None;
145 }
146}