From 63b58bbe05466a4230c8813d803800ce8c9b0bb0 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Fri, 3 Feb 2023 15:34:33 -0800 Subject: [PATCH] Added config file Added Steam and Among Us process detection Added ability to auto-run the blessed build --- Cargo.toml | 1 + src/app_data.rs | 80 +++++++++++++++++++++++++++++------ src/config.rs | 39 +++++++++++++++++ src/main.rs | 108 ++++++++++++++++++++++++++++-------------------- 4 files changed, 171 insertions(+), 57 deletions(-) create mode 100644 src/config.rs diff --git a/Cargo.toml b/Cargo.toml index ba46572..d5d2c42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ regex = "1.5" fs_extra = "1.2.0" dirs = "4.0.0" reqwest = {version = "0.11.11", features = ["blocking"]} +serde = {version= "1.0.143", features = ["derive"]} serde_json = "1.0" md-5 = "0.10.5" tokio = {version="1", features=["full"]} diff --git a/src/app_data.rs b/src/app_data.rs index c14d004..9dbcefb 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -1,5 +1,7 @@ // Crate imports use crate::among_us_version::*; +use crate::config; +use crate::config::*; use crate::semver::*; // Other imports @@ -47,10 +49,13 @@ pub struct AppData { pub installs_list: Vec, pub init_install_path: Option, pub init_download_url: Option, - pub steam_running: bool, + pub launcher_running: bool, + pub config: AppConfig, + pub among_us_launched: bool, + pub among_us_running: bool, // Thread handles - pub find_among_us_handle: Option>>, + pub find_among_us_handle: Option>>, pub determine_au_version_handle: Option>>, pub determine_tou_version_handle: Option>>, pub copy_au_handle: Option>, @@ -77,7 +82,10 @@ impl Default for AppData { installs_list: Vec::new(), init_install_path: None, init_download_url: None, - steam_running: false, + launcher_running: false, + config: AppConfig::default(), + among_us_launched: false, + among_us_running: false, find_among_us_handle: None, determine_au_version_handle: None, determine_tou_version_handle: None, @@ -92,12 +100,28 @@ impl AppData { if cfg!(windows) { unsafe { let tl = tasklist::Tasklist::new(); + self.launcher_running = false; for i in tl { if i.get_pname() == "steam.exe" { - self.steam_running = true; - println!("Steam running!"); + self.launcher_running = true; + // println!("Steam running!"); } else if i.get_pname() == "EpicGamesLauncher.exe" { - println!("Epic is running!"); + // println!("Epic is running!"); + } else { + } + } + } + } + } + + pub fn detect_running_among_us(&mut self) { + if cfg!(windows) { + unsafe { + let tl = tasklist::Tasklist::new(); + self.among_us_running = false; + for i in tl { + if i.get_pname() == "Among Us.exe" { + self.among_us_running = true; } } } @@ -261,16 +285,32 @@ impl AppData { let button_text = egui::RichText::new(button_string.clone()) .size(25.0) .color(egui::Color32::GREEN); - if ui.button(button_text).clicked() { + + let auto_run = self.config.auto_run_blessed + && !self.among_us_launched + && self.launcher_running; + + if ui + .add_enabled(!self.among_us_running, egui::Button::new(button_text)) + .clicked() + || auto_run + { crate::attempt_run_among_us(&clone); + self.among_us_launched = true; } } else { let button_text = egui::RichText::new(button_string.clone()).size(25.0); - if ui.button(button_text).clicked() { + if ui + .add_enabled(!self.among_us_running, egui::Button::new(button_text)) + .clicked() + { crate::attempt_run_among_us(&clone); + self.among_us_launched = true; } } + ui.set_enabled(true); + if !self.delete_mode { ui.set_visible(false); } @@ -323,7 +363,11 @@ impl eframe::App for AppData { if self.find_among_us_handle.as_ref().unwrap().is_finished() { if let Some(handle) = self.find_among_us_handle.take() { println!("Thread done, retrieving data..."); - self.among_us_path = handle.join().unwrap().unwrap(); + let (path, launcher_type) = handle.join().unwrap().unwrap(); + self.among_us_path = path.clone(); + self.config.among_us_path = Some(PathBuf::from(path)); + self.config.launcher_type = launcher_type; + config::save_config(&self.config); self.app_state = GlobalAppState::Initializing( InitializingState::DeterminingVersion, ); @@ -553,20 +597,32 @@ impl eframe::App for AppData { _ => {} }, GlobalAppState::Initialized => { + self.detect_running_stores(); + self.detect_running_among_us(); if self.update_installs_list { self.detect_installs(); self.update_installs_list = false; } egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { ui.checkbox(&mut self.delete_mode, "DELETE MODE"); + if ui + .checkbox(&mut self.config.auto_run_blessed, "Auto run blessed build") + .clicked() + { + config::save_config(&self.config); + }; }); egui::CentralPanel::default().show(ctx, |ui| { - if !self.steam_running { - let warning_text = egui::RichText::new("STEAM IS NOT RUNNING") + if !self.launcher_running { + let warning_string = match self.config.launcher_type { + LauncherType::Steam => "STEAM IS NOT RUNNING", + LauncherType::Epic => "EPIC IS NOT RUNNING", + _ => "UNKNOWN LAUNCHER USED", + }; + let warning_text = egui::RichText::new(warning_string) // .size(25.0) .color(egui::Color32::RED); ui.heading(warning_text); - self.detect_running_stores(); ctx.request_repaint(); } self.draw_layout(ui); diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..2a8760f --- /dev/null +++ b/src/config.rs @@ -0,0 +1,39 @@ +use serde::{Deserialize, Serialize}; +use std::{fs, path::PathBuf}; + +#[derive(Serialize, Deserialize, Default, Debug)] +pub enum LauncherType { + #[default] + None, + Steam, + Epic, +} + +#[derive(Serialize, Deserialize, Default, Debug)] +pub struct AppConfig { + pub launcher_type: LauncherType, + pub among_us_path: Option, + pub auto_run_blessed: bool, +} + +pub fn load_config() -> Option { + let mut config_path = dirs::data_dir().unwrap(); + config_path.push("town-of-us-updater"); + config_path.push("settings.json"); + if let Ok(string) = fs::read_to_string(config_path) { + let app_config: AppConfig = serde_json::from_str(string.as_str()).unwrap(); + return Some(app_config); + } else { + None + } +} + +pub fn save_config(app_data: &AppConfig) { + println!("Saving config"); + let mut config_path = dirs::data_dir().unwrap(); + config_path.push("town-of-us-updater"); + config_path.push("settings.json"); + + let json = serde_json::to_string_pretty(app_data).unwrap(); + fs::write(config_path, json).unwrap(); +} diff --git a/src/main.rs b/src/main.rs index d23fe86..7864332 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,13 @@ // Module definitions mod among_us_version; mod app_data; +mod config; mod semver; // Crate imports use among_us_version::*; use app_data::*; +use config::LauncherType; // Other imports use md5::{Digest, Md5}; @@ -15,7 +17,6 @@ use std::{ fs, io, path::{Path, PathBuf}, process, str, thread, - time::Duration, }; use fs_extra::{copy_items, dir}; @@ -31,6 +32,8 @@ use eframe::egui; use reqwest::StatusCode; +struct CombinedVersion(AmongUsVersion, SemVer); + static AMONG_US_APPID: &str = "945360"; fn attempt_run_among_us(install_path: &Path) { @@ -114,6 +117,7 @@ async fn _get_latest_updater_version() -> Result<(String, String), reqwest::Erro } fn main() { + let app_config = config::load_config().unwrap_or_default(); let version = env!("CARGO_PKG_VERSION"); let title_string: String = format!("Town of Us Updater - {}", version); let blessed_body = reqwest::blocking::get("https://tou.dormedas.com/blessed"); @@ -242,9 +246,9 @@ fn main() { if let Ok(existing_folder) = existing_found_folder { among_us_folder.push(existing_folder); } else { - let folder_opt: Option = detect_among_us_folder(); + let folder_opt: Option<(String, LauncherType)> = detect_among_us_folder(); if folder_opt.is_some() { - among_us_folder.push(folder_opt.unwrap()); + among_us_folder.push(folder_opt.unwrap().0); } if among_us_folder.exists() { @@ -267,7 +271,10 @@ fn main() { installs_list: Vec::new(), init_install_path: None, init_download_url: None, - steam_running: false, + launcher_running: false, + config: app_config, + among_us_launched: false, + among_us_running: false, find_among_us_handle: None, determine_au_version_handle: None, determine_tou_version_handle: None, @@ -422,56 +429,67 @@ fn copy_folder_contents_to_target>(source: T, dest: T) { fs_extra::dir::copy(source, dest, ©_opts).unwrap(); } -fn _detect_steam() -> Option { - None -} +fn detect_steam() -> Option<(String, LauncherType)> { + let mut library_folder_path: PathBuf = + PathBuf::from("C:\\Program Files (x86)\\Steam\\steamapps\\libraryfolders.vdf"); + if let Ok(steam_regkey) = Hive::LocalMachine.open( + r"SOFTWARE\WOW6432Node\Valve\Steam", + registry::Security::Read, + ) { + if let Ok(steam_folder) = steam_regkey.value("InstallPath") { + library_folder_path = PathBuf::from(steam_folder.to_string()); + library_folder_path.push("steamapps\\libraryfolders.vdf"); + println!("{:?}", steam_folder); + println!("{:?}", library_folder_path.to_str()); + } + } -fn _detect_epic() -> Option { - let _default_folder = String::from("C:\\Program Files\\Epic Games\\AmongUs"); - None -} + let library_folder = fs::read_to_string(library_folder_path.to_str().expect("Path invalid")); -fn detect_among_us_folder() -> Option { - if cfg!(windows) { - let mut library_folder_path: PathBuf = - PathBuf::from("C:\\Program Files (x86)\\Steam\\steamapps\\libraryfolders.vdf"); - if let Ok(steam_regkey) = Hive::LocalMachine.open( - r"SOFTWARE\WOW6432Node\Valve\Steam", - registry::Security::Read, - ) { - if let Ok(steam_folder) = steam_regkey.value("InstallPath") { - library_folder_path = PathBuf::from(steam_folder.to_string()); - library_folder_path.push("steamapps\\libraryfolders.vdf"); - println!("{:?}", steam_folder); - println!("{:?}", library_folder_path.to_str()); - } + if library_folder.is_ok() { + let mut library_folder_string: String = library_folder.unwrap(); + let appid_index = library_folder_string.find(AMONG_US_APPID); + if appid_index.is_none() { + println!("Among Us not found!"); + return None; + } else { + library_folder_string.truncate(appid_index.unwrap()); } - let library_folder = - fs::read_to_string(library_folder_path.to_str().expect("Path invalid")); - // thread::sleep(Duration::from_secs(5)); + let path_regex = Regex::new(r#"path"\s+"([Z-a\w\d\s\\\(\):]+)""#).unwrap(); + let caps: regex::CaptureMatches = path_regex.captures_iter(&library_folder_string); + let last_path = caps.last().unwrap(); + let start = last_path.get(last_path.len() - 1).unwrap(); - if library_folder.is_ok() { - let mut library_folder_string: String = library_folder.unwrap(); - let appid_index = library_folder_string.find(AMONG_US_APPID); - if appid_index.is_none() { - println!("Among Us not found!"); - return None; - } else { - library_folder_string.truncate(appid_index.unwrap()); - } - - let path_regex = Regex::new(r#"path"\s+"([Z-a\w\d\s\\\(\):]+)""#).unwrap(); - let caps: regex::CaptureMatches = path_regex.captures_iter(&library_folder_string); - let last_path = caps.last().unwrap(); - let start = last_path.get(last_path.len() - 1).unwrap(); - - return Some(format!( + return Some(( + format!( r"{}\\steamapps\\common\\Among Us\\", library_folder_string .get(start.start()..start.end()) .unwrap() - )); + ), + LauncherType::Steam, + )); + } + None +} + +fn detect_epic() -> Option<(String, LauncherType)> { + let default_folder = Path::new("C:\\Program Files\\Epic Games\\AmongUs"); + if default_folder.exists() { + return Some((default_folder.to_string_lossy().into(), LauncherType::Epic)); + } + None +} + +fn detect_among_us_folder() -> Option<(String, LauncherType)> { + if cfg!(windows) { + // Default to Steam + let return_val = detect_steam(); + if return_val.is_none() { + return detect_epic(); + } else { + return return_val; } } else { }