From 399b975aafdbb7e15265b7bf93dff1d6045943b8 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Tue, 31 Jan 2023 22:18:17 -0800 Subject: [PATCH] Version 4.1.0 Split AppData logic to its own, large, file Add Steam detection on Windows Added asynchronous installation of mod to make GUI responsive --- Cargo.toml | 3 +- src/app_data.rs | 580 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 297 +++---------------------- 3 files changed, 607 insertions(+), 273 deletions(-) create mode 100644 src/app_data.rs diff --git a/Cargo.toml b/Cargo.toml index 25ff0ec..ba46572 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "town-of-us-updater" -version = "4.0.2" +version = "4.1.0" edition = "2021" build = "src/build.rs" @@ -19,6 +19,7 @@ registry = "1" egui = "0.20.1" eframe = "0.20.1" rfd = "0.10" +tasklist = "0.2.12" [build-dependencies] embed-resource = "1.6" diff --git a/src/app_data.rs b/src/app_data.rs new file mode 100644 index 0000000..c14d004 --- /dev/null +++ b/src/app_data.rs @@ -0,0 +1,580 @@ +// Crate imports +use crate::among_us_version::*; +use crate::semver::*; + +// Other imports +use eframe::egui; +use std::thread::JoinHandle; +use std::{ + fs, + path::{Path, PathBuf}, + process, thread, +}; + +#[derive(PartialEq, Eq, Clone, Debug)] +pub enum InitializingState { + StartingGUI, + FindingAmongUs, + DeterminingVersion, + DeterminingToUVersion, + CopyingAmongUs, + UnmoddingAmongUs, + DownloadingZip, + Unzipping, + ModdingAmongUs, +} + +#[derive(PartialEq, Eq, Clone, Debug)] +pub enum GlobalAppState { + Initializing(InitializingState), + Initialized, + Installing, + Playing, +} + +#[derive(Debug)] +pub struct AppData { + pub among_us_path: String, + pub installs_path: String, + pub version: SemVer, + pub delete_mode: bool, + pub among_us_version: AmongUsVersion, + pub data_path: String, + pub app_state: GlobalAppState, + pub blessed_version: String, + pub update_installs_list: bool, + pub installs_last_update_time: std::time::Instant, + pub installs_list: Vec, + pub init_install_path: Option, + pub init_download_url: Option, + pub steam_running: bool, + + // Thread handles + pub find_among_us_handle: Option>>, + pub determine_au_version_handle: Option>>, + pub determine_tou_version_handle: Option>>, + pub copy_au_handle: Option>, + pub download_tou_handle: Option>, +} + +impl Default for AppData { + fn default() -> AppData { + AppData { + among_us_path: String::new(), + installs_path: String::new(), + version: SemVer { + major: 0, + minor: 0, + patch: 0, + }, + delete_mode: false, + among_us_version: AmongUsVersion::default(), + data_path: String::new(), + app_state: GlobalAppState::Initialized, + blessed_version: String::new(), + update_installs_list: true, + installs_last_update_time: std::time::Instant::now(), + installs_list: Vec::new(), + init_install_path: None, + init_download_url: None, + steam_running: false, + find_among_us_handle: None, + determine_au_version_handle: None, + determine_tou_version_handle: None, + copy_au_handle: None, + download_tou_handle: None, + } + } +} + +impl AppData { + pub fn detect_running_stores(&mut self) { + if cfg!(windows) { + unsafe { + let tl = tasklist::Tasklist::new(); + for i in tl { + if i.get_pname() == "steam.exe" { + self.steam_running = true; + println!("Steam running!"); + } else if i.get_pname() == "EpicGamesLauncher.exe" { + println!("Epic is running!"); + } + } + } + } + } + + pub fn on_path_added(&mut self) { + if self.among_us_path.is_empty() { + return; + } + + if let Some(among_us_version) = + crate::determine_among_us_version(String::from(self.among_us_path.clone())) + { + self.among_us_version = among_us_version.clone(); + println!("AmongUsVersion: {}", among_us_version); + } + + self.app_state = GlobalAppState::Initializing(InitializingState::DeterminingVersion); + let ver_url: (String, String, bool) = + crate::determine_town_of_us_url(self.among_us_version.to_string().clone()).unwrap(); + + let version_smash = format!("{}-{}", self.among_us_version, ver_url.0.clone()); + let new_installed_path: PathBuf = [self.installs_path.as_str(), version_smash.as_str()] + .iter() + .collect(); + + if !Path::exists(&new_installed_path) { + println!("Copying Among Us to cache location..."); + crate::copy_folder_to_target(self.among_us_path.clone(), self.installs_path.clone()); + + let among_us_path: PathBuf = [self.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 + crate::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 = [self.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 client = reqwest::blocking::Client::builder() + .timeout(None) + .build() + .unwrap(); + let zip_request = client.get(ver_url.1.clone()).build().unwrap(); + let zip = client.execute(zip_request).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(self.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 = [self.data_path.as_str(), root_folder_path.as_str(), "."] + .iter() + .collect(); + println!("{}", extracted_path.to_str().unwrap()); + crate::copy_folder_contents_to_target( + extracted_path.to_str().unwrap(), + new_installed_path.to_str().unwrap(), + ); + } + self.app_state = GlobalAppState::Initialized; + self.update_installs_list = true; + } + + pub fn detect_installs(&mut self) { + let install_iter = fs::read_dir(self.installs_path.clone()); + if let Ok(iter) = install_iter { + self.installs_list = iter + .map(|elem| PathBuf::from(elem.unwrap().file_name())) + .collect(); + } else { + self.installs_list.clear(); + } + self.installs_last_update_time = std::time::Instant::now(); + } + + fn draw_layout(&mut self, ui: &mut egui::Ui) { + let now = std::time::Instant::now(); + if now.duration_since(self.installs_last_update_time) > std::time::Duration::from_secs(10) { + self.detect_installs(); + } + + let mut collection = self.installs_list.clone(); + + if collection.is_empty() { + if ui.button("Locate your Among Us Directory").clicked() { + if let Some(mut path) = rfd::FileDialog::new().pick_file() { + path.pop(); + self.among_us_path = path.display().to_string(); + self.on_path_added(); + } + } + return; + } + + collection.reverse(); + let mut auv_array: Vec = Vec::new(); + + for i in &collection { + let existing_ver_smash = i; + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); + let among_us_version = AmongUsVersion::from(ver_smash_split.next().unwrap()); + if !auv_array.contains(&among_us_version) { + auv_array.push(among_us_version); + } + } + + auv_array.sort(); + auv_array.reverse(); + + ui.separator(); + for i in &auv_array { + ui.label( + egui::RichText::new(format!("Among Us {}", i.as_american_string())).size(35.0), + ); + for j in &collection { + let existing_ver_smash = j; + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); + let mut blessed_split = self.blessed_version.as_str().split('-'); + let among_us_version = AmongUsVersion::from(ver_smash_split.next().unwrap()); + let tou_version = ver_smash_split.next().unwrap(); + let blessed_version = AmongUsVersion::from(blessed_split.next().unwrap()); + let blessed_tou_version = blessed_split.next().unwrap(); + let button_string: String = format!("Town of Us {}", tou_version); + if i == &among_us_version { + let mut clone: PathBuf = PathBuf::from(self.installs_path.clone()); + clone.push(existing_ver_smash.clone()); + ui.horizontal(|ui| { + if i == &blessed_version && tou_version == blessed_tou_version { + let button_text = egui::RichText::new(button_string.clone()) + .size(25.0) + .color(egui::Color32::GREEN); + if ui.button(button_text).clicked() { + crate::attempt_run_among_us(&clone); + } + } else { + let button_text = egui::RichText::new(button_string.clone()).size(25.0); + if ui.button(button_text).clicked() { + crate::attempt_run_among_us(&clone); + } + } + + if !self.delete_mode { + ui.set_visible(false); + } + + let button_text = egui::RichText::new("DELETE") + .size(25.0) + .color(egui::Color32::RED); + + if ui.button(button_text).clicked() { + if i != &blessed_version || tou_version != blessed_tou_version { + crate::attempt_delete_among_us(&clone); + self.update_installs_list = true; + } + } + + ui.set_visible(true); + }); + } + } + ui.separator(); + } + } +} + +impl eframe::App for AppData { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + match &mut self.app_state { + GlobalAppState::Initializing(sub_state) => match sub_state { + InitializingState::StartingGUI => { + if !self.among_us_path.is_empty() { + // If we pulled in a cached location, skip straight to ToU version check + self.app_state = + GlobalAppState::Initializing(InitializingState::DeterminingVersion); + } else { + self.app_state = + GlobalAppState::Initializing(InitializingState::FindingAmongUs); + } + + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Initializing..."); + }); + ctx.request_repaint(); + } + InitializingState::FindingAmongUs => { + // if !self.among_us_path.is_empty() { + // self.app_state = + // GlobalAppState::Initializing(InitializingState::DeterminingVersion); + // } + if self.find_among_us_handle.as_ref().is_some() { + 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(); + self.app_state = GlobalAppState::Initializing( + InitializingState::DeterminingVersion, + ); + } + } + } else { + println!("Spawning thread..."); + self.find_among_us_handle = Some(thread::spawn(|| { + return crate::detect_among_us_folder(); + })); + } + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Finding Among Us..."); + }); + ctx.request_repaint(); + } + InitializingState::DeterminingVersion => { + if self.among_us_version != AmongUsVersion::default() { + self.app_state = + GlobalAppState::Initializing(InitializingState::DeterminingToUVersion); + } else { + if self.determine_au_version_handle.as_ref().is_some() { + if self + .determine_au_version_handle + .as_ref() + .unwrap() + .is_finished() + { + if let Some(handle) = self.determine_au_version_handle.take() { + println!("Thread done, retrieving data..."); + self.among_us_version = handle.join().unwrap().unwrap(); + } + } + } else { + println!("Spawning thread..."); + let path = self.among_us_path.clone(); + self.determine_au_version_handle = Some(thread::spawn(move || { + return crate::determine_among_us_version(path); + })); + } + } + + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Determining Among Us Version..."); + }); + ctx.request_repaint(); + } + InitializingState::DeterminingToUVersion => { + if self.determine_tou_version_handle.as_ref().is_some() { + if self + .determine_tou_version_handle + .as_ref() + .unwrap() + .is_finished() + { + if let Some(handle) = self.determine_tou_version_handle.take() { + println!("Thread done, retrieving data..."); + let result = handle.join().unwrap().unwrap(); + let version_smash = + format!("{}-{}", self.among_us_version, result.0.clone()); + let new_path: PathBuf = + [self.installs_path.as_str(), version_smash.as_str()] + .iter() + .collect(); + self.init_install_path = Some(new_path.clone()); + self.init_download_url = Some(result.1.clone()); + + if !Path::exists(&new_path) { + self.app_state = GlobalAppState::Initializing( + InitializingState::CopyingAmongUs, + ); + } else { + self.app_state = GlobalAppState::Initialized; + } + } + } + } else { + println!("Spawning thread..."); + let ver = self.among_us_version.clone(); + self.determine_tou_version_handle = Some(thread::spawn(move || { + return crate::determine_town_of_us_url(ver.to_string()); + })); + } + + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Determining Among Us Version..."); + }); + ctx.request_repaint(); + } + InitializingState::CopyingAmongUs => { + if self.copy_au_handle.as_ref().is_some() { + if self.copy_au_handle.as_ref().unwrap().is_finished() { + self.copy_au_handle = None; + self.app_state = + GlobalAppState::Initializing(InitializingState::UnmoddingAmongUs); + } + } else { + println!("Spawning thread..."); + let among_us_path = self.among_us_path.clone(); + let installs_path = self.installs_path.clone(); + self.copy_au_handle = Some(thread::spawn(move || { + println!("Copying Among Us to cache location..."); + crate::copy_folder_to_target(among_us_path, installs_path); + })); + } + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Copying Among Us..."); + }); + ctx.request_repaint(); + } + InitializingState::UnmoddingAmongUs => { + if self.copy_au_handle.as_ref().is_some() { + if self.copy_au_handle.as_ref().unwrap().is_finished() { + self.copy_au_handle = None; + self.app_state = + GlobalAppState::Initializing(InitializingState::DownloadingZip); + } + } else { + // TODO: This sucks + let new_installed_path = self.init_install_path.as_ref().unwrap().clone(); + let installs_path = self.installs_path.clone(); + self.copy_au_handle = Some(thread::spawn(move || { + let among_us_path: PathBuf = + [installs_path.as_str(), "Among Us"].iter().collect(); + // Un-mod whatever we found if it's modded + crate::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(); + })); + } + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Unmodding Among Us..."); + }); + ctx.request_repaint(); + } + InitializingState::DownloadingZip => { + if self.download_tou_handle.as_ref().is_some() { + if self.download_tou_handle.as_ref().unwrap().is_finished() { + self.download_tou_handle = None; + self.app_state = + GlobalAppState::Initializing(InitializingState::Unzipping); + } + } else { + let data_path = self.data_path.clone(); + let download_url = self.init_download_url.as_ref().unwrap().clone(); + self.download_tou_handle = Some(thread::spawn(move || { + let mut download_path: PathBuf = [data_path.as_str()].iter().collect(); + let downloaded_filename: &str = + download_url.rsplit('/').next().unwrap(); + download_path.push(downloaded_filename); + + if !download_path.exists() { + println!( + "Downloading Town of Us... Please be patient! [{}]", + download_url.clone() + ); + let client = reqwest::blocking::Client::builder() + .timeout(None) + .build() + .unwrap(); + let zip_request = client.get(download_url.clone()).build().unwrap(); + let zip = client.execute(zip_request).unwrap().bytes().unwrap(); + fs::write(download_path.clone(), zip).unwrap(); + } + })); + } + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Downloading Town of Us..."); + }); + ctx.request_repaint(); + } + InitializingState::Unzipping => { + if self.download_tou_handle.as_ref().is_some() { + if self.download_tou_handle.as_ref().unwrap().is_finished() { + self.download_tou_handle = None; + self.app_state = GlobalAppState::Initialized; + } + } else { + let data_path = self.data_path.clone(); + let download_url = self.init_download_url.as_ref().unwrap().clone(); + let new_installed_path = self.init_install_path.as_ref().unwrap().clone(); + self.download_tou_handle = Some(thread::spawn(move || { + let mut download_path: PathBuf = [data_path.as_str()].iter().collect(); + let downloaded_filename: &str = + download_url.rsplit('/').next().unwrap(); + download_path.push(downloaded_filename); + 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_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_path.as_str(), root_folder_path.as_str(), "."] + .iter() + .collect(); + println!("{}", extracted_path.to_str().unwrap()); + crate::copy_folder_contents_to_target( + extracted_path.to_str().unwrap(), + new_installed_path.to_str().unwrap(), + ); + })); + } + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Extracting Town of Us..."); + ui.heading("Modding Among Us..."); + }); + ctx.request_repaint(); + } + _ => {} + }, + GlobalAppState::Initialized => { + 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"); + }); + egui::CentralPanel::default().show(ctx, |ui| { + if !self.steam_running { + let warning_text = egui::RichText::new("STEAM IS NOT RUNNING") + // .size(25.0) + .color(egui::Color32::RED); + ui.heading(warning_text); + self.detect_running_stores(); + ctx.request_repaint(); + } + self.draw_layout(ui); + }); + } + _ => {} + } + // app_data.on_path_added(); + // app_data.detect_installs(); // Initial check since we only update every 10s + } +} diff --git a/src/main.rs b/src/main.rs index e19fdbb..d23fe86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,21 @@ -// Modules +// Module definitions mod among_us_version; +mod app_data; mod semver; -// Uses +// Crate imports use among_us_version::*; +use app_data::*; +// Other imports use md5::{Digest, Md5}; use semver::*; use std::{ fs, io, path::{Path, PathBuf}, - process, str, + process, str, thread, + time::Duration, }; use fs_extra::{copy_items, dir}; @@ -27,180 +31,6 @@ use eframe::egui; use reqwest::StatusCode; -#[derive(PartialEq, Eq, Clone, Debug)] -pub enum InitializingState { - StartingGUI, - DeterminingVersion, - CopyingAmongUs, - UnmoddingAmongUs, - DownloadingZip, - Unzipping, - CopyingZipIn, -} - -#[derive(PartialEq, Eq, Clone, Debug)] -pub enum GlobalAppState { - Initializing(InitializingState), - Initialized, - Installing, - Playing, -} - -#[derive(Clone, Debug)] -pub struct AppData { - pub among_us_path: String, - pub installs_path: String, - pub version: SemVer, - pub delete_mode: bool, - pub among_us_version: AmongUsVersion, - pub data_path: String, - pub app_state: GlobalAppState, - pub blessed_version: String, - pub update_installs_list: bool, - pub installs_last_update_time: std::time::Instant, - pub installs_list: Vec, -} - -impl Default for AppData { - fn default() -> AppData { - AppData { - among_us_path: String::new(), - installs_path: String::new(), - version: SemVer { - major: 0, - minor: 0, - patch: 0, - }, - delete_mode: false, - among_us_version: AmongUsVersion::default(), - data_path: String::new(), - app_state: GlobalAppState::Initialized, - blessed_version: String::new(), - update_installs_list: true, - installs_last_update_time: std::time::Instant::now(), - installs_list: Vec::new(), - } - } -} - -impl AppData { - fn detect_installs(&mut self) { - let install_iter = fs::read_dir(self.installs_path.clone()); - if let Ok(iter) = install_iter { - self.installs_list = iter - .map(|elem| PathBuf::from(elem.unwrap().file_name())) - .collect(); - } else { - self.installs_list.clear(); - } - self.installs_last_update_time = std::time::Instant::now(); - } - - fn draw_layout(&mut self, ui: &mut egui::Ui) { - let now = std::time::Instant::now(); - if now.duration_since(self.installs_last_update_time) > std::time::Duration::from_secs(10) { - self.detect_installs(); - } - - let mut collection = self.installs_list.clone(); - - if collection.is_empty() { - if ui.button("Locate your Among Us Directory").clicked() { - if let Some(mut path) = rfd::FileDialog::new().pick_file() { - path.pop(); - self.among_us_path = path.display().to_string(); - self.on_path_added(); - } - } - return; - } - - collection.reverse(); - let mut auv_array: Vec = Vec::new(); - - for i in &collection { - let existing_ver_smash = i; - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); - let among_us_version = AmongUsVersion::from(ver_smash_split.next().unwrap()); - if !auv_array.contains(&among_us_version) { - auv_array.push(among_us_version); - } - } - - auv_array.sort(); - auv_array.reverse(); - - ui.separator(); - for i in &auv_array { - ui.label( - egui::RichText::new(format!("Among Us {}", i.as_american_string())).size(35.0), - ); - for j in &collection { - let existing_ver_smash = j; - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); - let mut blessed_split = self.blessed_version.as_str().split('-'); - let among_us_version = AmongUsVersion::from(ver_smash_split.next().unwrap()); - let tou_version = ver_smash_split.next().unwrap(); - let blessed_version = AmongUsVersion::from(blessed_split.next().unwrap()); - let blessed_tou_version = blessed_split.next().unwrap(); - let button_string: String = format!("Town of Us {}", tou_version); - if i == &among_us_version { - let mut clone: PathBuf = PathBuf::from(self.installs_path.clone()); - clone.push(existing_ver_smash.clone()); - ui.horizontal(|ui| { - if i == &blessed_version && tou_version == blessed_tou_version { - let button_text = egui::RichText::new(button_string.clone()) - .size(25.0) - .color(egui::Color32::GREEN); - if ui.button(button_text).clicked() { - crate::attempt_run_among_us(&clone); - } - } else { - let button_text = egui::RichText::new(button_string.clone()).size(25.0); - if ui.button(button_text).clicked() { - crate::attempt_run_among_us(&clone); - } - } - - if !self.delete_mode { - ui.set_visible(false); - } - - let button_text = egui::RichText::new("DELETE") - .size(25.0) - .color(egui::Color32::RED); - - if ui.button(button_text).clicked() { - if i != &blessed_version || tou_version != blessed_tou_version { - crate::attempt_delete_among_us(&clone); - self.update_installs_list = true; - } - } - - ui.set_visible(true); - }); - } - } - ui.separator(); - } - } -} - -impl eframe::App for AppData { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - 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"); - }); - egui::CentralPanel::default().show(ctx, |ui| { - self.draw_layout(ui); - }); - } -} - static AMONG_US_APPID: &str = "945360"; fn attempt_run_among_us(install_path: &Path) { @@ -283,97 +113,6 @@ async fn _get_latest_updater_version() -> Result<(String, String), reqwest::Erro Ok((String::from("no"), String::from("yes"))) } -impl AppData { - fn on_path_added(&mut self) { - if self.among_us_path.is_empty() { - return; - } - - if let Some(among_us_version) = - determine_among_us_version(String::from(self.among_us_path.clone())) - { - self.among_us_version = among_us_version.clone(); - println!("AmongUsVersion: {}", among_us_version); - } - - self.app_state = GlobalAppState::Initializing(InitializingState::DeterminingVersion); - let ver_url: (String, String, bool) = - determine_town_of_us_url(self.among_us_version.to_string().clone()).unwrap(); - - let version_smash = format!("{}-{}", self.among_us_version, ver_url.0.clone()); - let new_installed_path: PathBuf = [self.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(self.among_us_path.clone(), self.installs_path.clone()); - - let among_us_path: PathBuf = [self.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 = [self.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 client = reqwest::blocking::Client::builder() - .timeout(None) - .build() - .unwrap(); - let zip_request = client.get(ver_url.1.clone()).build().unwrap(); - let zip = client.execute(zip_request).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(self.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 = [self.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(), - ); - } - self.app_state = GlobalAppState::Initialized; - self.update_installs_list = true; - } -} - fn main() { let version = env!("CARGO_PKG_VERSION"); let title_string: String = format!("Town of Us Updater - {}", version); @@ -514,7 +253,8 @@ fn main() { } let mut app_data: AppData = AppData { - among_us_path: String::from(among_us_folder.clone().to_str().unwrap()), + // among_us_path: String::from(among_us_folder.clone().to_str().unwrap()), + among_us_path: String::new(), installs_path: String::from(installs_path.clone().to_str().unwrap()), version: SemVer::from(version), delete_mode: false, @@ -525,6 +265,14 @@ fn main() { update_installs_list: true, installs_last_update_time: std::time::Instant::now(), installs_list: Vec::new(), + init_install_path: None, + init_download_url: None, + steam_running: false, + find_among_us_handle: None, + determine_au_version_handle: None, + determine_tou_version_handle: None, + copy_au_handle: None, + download_tou_handle: None, }; // DETERMINE AMONG US VERSION @@ -542,13 +290,17 @@ fn main() { println!("Launching main window..."); - launch_better_crewlink().unwrap_or(()); + // Tell better crewlink to launch somewhere else + thread::spawn(|| { + launch_better_crewlink().unwrap_or(()); + }); let mut native_options = eframe::NativeOptions::default(); native_options.min_window_size = Some(egui::vec2(425.0, 400.0)); native_options.initial_window_size = Some(egui::vec2(425.0, 400.0)); - app_data.on_path_added(); - app_data.detect_installs(); // Initial check since we only update every 10s + + app_data.detect_running_stores(); + eframe::run_native( title_string.as_str(), native_options, @@ -697,6 +449,7 @@ fn detect_among_us_folder() -> Option { let library_folder = fs::read_to_string(library_folder_path.to_str().expect("Path invalid")); + // thread::sleep(Duration::from_secs(5)); if library_folder.is_ok() { let mut library_folder_string: String = library_folder.unwrap();