diff --git a/src/among_us_launcher_widget.rs b/src/among_us_launcher_widget.rs index 359a0cb..e6d6b80 100644 --- a/src/among_us_launcher_widget.rs +++ b/src/among_us_launcher_widget.rs @@ -6,6 +6,9 @@ use druid::{ use std::{fs, io, path::PathBuf}; pub const ATTEMPT_INSTALL: Selector = Selector::new("town-of-us-updater.attempt_install"); +pub const DETERMINE_AMONG_US_VERSION: Selector = + Selector::new("town-of-us-updater.determine_among_us_version"); +pub const COPY_FOLDER: Selector = Selector::new("town-of-us-updater.copy_folder"); pub struct AmongUsLauncherWidget { pub root: WidgetPod>, @@ -15,6 +18,15 @@ impl AmongUsLauncherWidget { pub fn build_widget(&mut self, data: &AppData) { let mut flex: Flex = Flex::column(); + match &data.app_state { + crate::GlobalAppState::Initializing(_a) => { + let label = Label::new("Initializing...").with_text_size(24.0).center(); + flex.add_flex_child(label, 1.0); + self.root = WidgetPod::new(flex); + return; + } + _ => {} + } // Find existing installs, make buttons for them let install_iter = fs::read_dir(data.installs_path.clone()); @@ -144,9 +156,12 @@ impl Widget for AmongUsLauncherWidget { } fn update(&mut self, ctx: &mut UpdateCtx, old_data: &AppData, data: &AppData, env: &Env) { self.root.update(ctx, data, env); + println!("{:?}", data); if old_data.among_us_path.is_empty() && !data.among_us_path.is_empty() { - ctx.submit_command(ATTEMPT_INSTALL); + ctx.submit_command(DETERMINE_AMONG_US_VERSION); // println!("Detect Stuff"); + } else if old_data.among_us_version != data.among_us_version { + ctx.submit_command(ATTEMPT_INSTALL); } // println!("Update!"); self.build_widget(data); diff --git a/src/main.rs b/src/main.rs index 10df346..ec5a53e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ use fs_extra::{copy_items, dir}; use regex::Regex; +#[cfg(target_os = "windows")] use registry::Hive; // GUI stuff @@ -27,6 +28,25 @@ use druid::{ WidgetPod, WindowDesc, WindowId, }; +#[derive(PartialEq, Eq, Data, Clone, Debug)] +pub enum InitializingState { + StartingGUI, + DeterminingVersion, + CopyingAmongUs, + UnmoddingAmongUs, + DownloadingZip, + Unzipping, + CopyingZipIn, +} + +#[derive(PartialEq, Eq, Data, Clone, Debug)] +pub enum GlobalAppState { + Initializing(InitializingState), + Initialized, + Installing, + Playing, +} + struct Delegate; #[derive(Data, Clone, Debug)] @@ -37,6 +57,7 @@ pub struct AppData { pub initialized: bool, pub among_us_version: AmongUsVersion, pub data_path: String, + pub app_state: GlobalAppState, } static AMONG_US_APPID: &str = "945360"; @@ -126,7 +147,7 @@ impl AppDelegate for Delegate { ctx: &mut DelegateCtx, ) { if !data.among_us_path.is_empty() { - ctx.submit_command(ATTEMPT_INSTALL); + ctx.submit_command(DETERMINE_AMONG_US_VERSION); } } fn command( @@ -151,87 +172,89 @@ impl AppDelegate for Delegate { //Application::global().quit(); return Handled::Yes; - } else if let Some(_a) = cmd.get(among_us_launcher_widget::ATTEMPT_INSTALL) { + } else if let Some(_a) = cmd.get(among_us_launcher_widget::DETERMINE_AMONG_US_VERSION) { if let Some(among_us_version) = determine_among_us_version(String::from(data.among_us_path.clone())) { data.among_us_version = among_us_version.clone(); println!("AmongUsVersion: {}", among_us_version); - let ver_url: (String, String, bool) = - determine_town_of_us_url(among_us_version.to_string().clone()).unwrap(); + } + } else if let Some(_a) = cmd.get(among_us_launcher_widget::ATTEMPT_INSTALL) { + data.app_state = GlobalAppState::Initializing(InitializingState::DeterminingVersion); + let ver_url: (String, String, bool) = + determine_town_of_us_url(data.among_us_version.to_string().clone()).unwrap(); - let version_smash = format!("{}-{}", among_us_version, ver_url.0.clone()); - let new_installed_path: PathBuf = - [data.installs_path.as_str(), version_smash.as_str()] + let version_smash = format!("{}-{}", data.among_us_version, ver_url.0.clone()); + let new_installed_path: PathBuf = [data.installs_path.as_str(), version_smash.as_str()] + .iter() + .collect(); + + if !Path::exists(&new_installed_path) { + println!("Copying Among Us to cache location..."); + copy_folder_to_target(data.among_us_path.clone(), data.installs_path.clone()); + + let among_us_path: PathBuf = + [data.installs_path.as_str(), "Among Us"].iter().collect(); + + if !among_us_path.to_str().unwrap().contains("Among Us") { + process::exit(0); + } + + // Un-mod whatever we found if it's modded + unmod_among_us_folder(&among_us_path); + + println!( + "Renaming {} to {}", + among_us_path.to_str().unwrap(), + new_installed_path.to_str().unwrap() + ); + + let mut perms = fs::metadata(among_us_path.clone()).unwrap().permissions(); + perms.set_readonly(false); + fs::set_permissions(among_us_path.clone(), perms).unwrap(); + + fs::rename(among_us_path, new_installed_path.clone()).unwrap(); + let mut download_path: PathBuf = [data.data_path.as_str()].iter().collect(); + let downloaded_filename: &str = ver_url.1.rsplit('/').next().unwrap(); + download_path.push(downloaded_filename); + + if !download_path.exists() { + // println!("{:?}", download_path); + println!( + "Downloading Town of Us... Please be patient! [{}]", + ver_url.1.clone() + ); + let zip = reqwest::blocking::get(ver_url.1.clone()) + .unwrap() + .bytes() + .unwrap(); + fs::write(download_path.clone(), zip).unwrap(); + } + + let opened_zip = fs::File::open(download_path.clone()).unwrap(); + println!("Extracting mod zip file..."); + let mut archive = zip::ZipArchive::new(opened_zip).unwrap(); + archive.extract(data.data_path.clone()).unwrap(); + + fs::remove_file(download_path).unwrap(); + + let mut root_folder_path = String::new(); + for i in archive.file_names() { + root_folder_path = String::from(i.split('/').next().unwrap()); + break; + } + let extracted_path: PathBuf = + [data.data_path.as_str(), root_folder_path.as_str(), "."] .iter() .collect(); - - if !Path::exists(&new_installed_path) { - println!("Copying Among Us to cache location..."); - copy_folder_to_target(data.among_us_path.clone(), data.installs_path.clone()); - - let among_us_path: PathBuf = - [data.installs_path.as_str(), "Among Us\\"].iter().collect(); - - if !among_us_path.to_str().unwrap().contains("Among Us") { - process::exit(0); - } - - // Un-mod whatever we found if it's modded - unmod_among_us_folder(&among_us_path); - - println!( - "Renaming {} to {}", - among_us_path.to_str().unwrap(), - new_installed_path.to_str().unwrap() - ); - - let mut perms = fs::metadata(among_us_path.clone()).unwrap().permissions(); - perms.set_readonly(false); - fs::set_permissions(among_us_path.clone(), perms).unwrap(); - - fs::rename(among_us_path, new_installed_path.clone()).unwrap(); - let mut download_path: PathBuf = [data.data_path.as_str()].iter().collect(); - let downloaded_filename: &str = ver_url.1.rsplit('/').next().unwrap(); - download_path.push(downloaded_filename); - - if !download_path.exists() { - // println!("{:?}", download_path); - println!( - "Downloading Town of Us... Please be patient! [{}]", - ver_url.1.clone() - ); - let zip = reqwest::blocking::get(ver_url.1.clone()) - .unwrap() - .bytes() - .unwrap(); - fs::write(download_path.clone(), zip).unwrap(); - } - - let opened_zip = fs::File::open(download_path.clone()).unwrap(); - println!("Extracting mod zip file..."); - let mut archive = zip::ZipArchive::new(opened_zip).unwrap(); - archive.extract(data.data_path.clone()).unwrap(); - - fs::remove_file(download_path).unwrap(); - - let mut root_folder_path = String::new(); - for i in archive.file_names() { - root_folder_path = String::from(i.split('/').next().unwrap()); - break; - } - let extracted_path: PathBuf = - [data.data_path.as_str(), root_folder_path.as_str(), "."] - .iter() - .collect(); - println!("{}", extracted_path.to_str().unwrap()); - copy_folder_contents_to_target( - extracted_path.to_str().unwrap(), - new_installed_path.to_str().unwrap(), - ); - } + println!("{}", extracted_path.to_str().unwrap()); + copy_folder_contents_to_target( + extracted_path.to_str().unwrap(), + new_installed_path.to_str().unwrap(), + ); } data.initialized = !data.initialized; + data.app_state = GlobalAppState::Initialized; return Handled::Yes; } @@ -284,6 +307,7 @@ fn main() { initialized: false, among_us_version: AmongUsVersion::default(), data_path: String::from(data_path.clone().to_str().unwrap()), + app_state: GlobalAppState::Initializing(InitializingState::StartingGUI), }; let mut root_column: druid::widget::Flex = druid::widget::Flex::column(); @@ -386,7 +410,7 @@ fn determine_town_of_us_url(among_us_version: String) -> Option<(String, String, } fn determine_among_us_version(folder_root: String) -> Option { - let asset_file = format!("{}\\Among Us_Data\\globalgamemanagers", folder_root); + let asset_file = format!("{}/Among Us_Data/globalgamemanagers", folder_root); const TARGET_BYTES_LEN: usize = 16; @@ -452,40 +476,47 @@ fn _detect_epic() -> Option { } fn detect_among_us_folder() -> Option { - 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") { - println!("{:?}", steam_folder); - } - } - - let library_folder = - fs::read_to_string("C:\\Program Files (x86)\\Steam\\steamapps\\libraryfolders.vdf"); - - if library_folder.is_ok() { - println!("Steam is on C:\\ drive!"); - 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()); + 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()); + } } - 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(); + let library_folder = + fs::read_to_string(library_folder_path.to_str().expect("Path invalid")); - return Some(format!( - "{}\\\\steamapps\\\\common\\\\Among Us\\\\", - library_folder_string - .get(start.start()..start.end()) - .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!( + r"{}\\steamapps\\common\\Among Us\\", + library_folder_string + .get(start.start()..start.end()) + .unwrap() + )); + } + } else { } None }