From d6e3a7133bc8f626a62f70cb796bd3323adcb2e1 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Mon, 29 Aug 2022 18:41:03 -0700 Subject: [PATCH 1/6] Move AmongUsVersion to its own file. Concatenate and reduce imports. --- src/among_us_version.rs | 38 +++++++++++++++++++ src/main.rs | 84 +++++++++++++++-------------------------- 2 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 src/among_us_version.rs diff --git a/src/among_us_version.rs b/src/among_us_version.rs new file mode 100644 index 0000000..82473e8 --- /dev/null +++ b/src/among_us_version.rs @@ -0,0 +1,38 @@ +use std::fmt; +#[derive(Ord, PartialOrd, Eq, PartialEq)] +pub struct AmongUsVersion { + year: i32, + month: i32, + day: i32, +} + +impl fmt::Display for AmongUsVersion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}.{}.{}", self.year, self.month, self.day) + } +} + +impl From<&str> for AmongUsVersion { + fn from(s: &str) -> AmongUsVersion { + // Ignore a prepending "v" + let tmp_str = s.replace("v", ""); + + let v: Vec<&str> = tmp_str.split(".").collect(); + + AmongUsVersion { + year: i32::from_str_radix(v[0], 10).unwrap(), + month: i32::from_str_radix(v[1], 10).unwrap(), + day: i32::from_str_radix(v[2], 10).unwrap(), + } + } +} + +impl From<(i32, i32, i32)> for AmongUsVersion { + fn from(s: (i32, i32, i32)) -> AmongUsVersion { + AmongUsVersion { + year: s.0, + month: s.1, + day: s.2, + } + } +} diff --git a/src/main.rs b/src/main.rs index 3931984..d4a7226 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,21 @@ -use std::cell::RefCell; -use std::path::{Path, PathBuf}; -use std::rc::Rc; -use std::str; -use std::*; +// Modules +mod among_us_version; + +// Uses +use among_us_version::*; + +use std::{cell::RefCell, fs, io, path::Path, path::PathBuf, process, rc::Rc, str}; -use druid::widget::*; -use druid::{ - commands, AppDelegate, AppLauncher, Application, Data, DelegateCtx, Env, FileDialogOptions, - Handled, Target, WidgetExt, WindowDesc, -}; use fs_extra::{copy_items, dir}; + use regex::Regex; +// GUI stuff +use druid::{ + commands, widget::*, AppDelegate, AppLauncher, Application, Data, DelegateCtx, Env, + FileDialogOptions, Handled, Target, WidgetExt, WindowDesc, +}; + struct Delegate; #[derive(Data, Clone)] @@ -21,36 +25,12 @@ struct AppData { static AMONG_US_APPID: &'static str = "945360"; -#[derive(Ord, PartialOrd, Eq, PartialEq)] -struct AmongUsVersion { - year: i32, - month: i32, - day: i32, -} - -impl fmt::Display for AmongUsVersion { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}.{}.{}", self.year, self.month, self.day) - } -} - -impl From<&str> for AmongUsVersion { - fn from(s: &str) -> AmongUsVersion { - let v: Vec<&str> = s.split(".").collect(); - AmongUsVersion { - year: i32::from_str_radix(v[0], 10).unwrap(), - month: i32::from_str_radix(v[1], 10).unwrap(), - day: i32::from_str_radix(v[2], 10).unwrap(), - } - } -} - fn attempt_run_among_us(install_path: &Path) { - let executable_path: path::PathBuf = [install_path.to_str().unwrap(), "Among Us.exe"] + let executable_path: PathBuf = [install_path.to_str().unwrap(), "Among Us.exe"] .iter() .collect(); - std::process::Command::new(executable_path.to_str().unwrap()) + process::Command::new(executable_path.to_str().unwrap()) .spawn() .unwrap(); } @@ -170,7 +150,7 @@ async fn main() { // DETERMINE AMONG US VERSION - let mut among_us_folder = path::PathBuf::new(); + let mut among_us_folder = PathBuf::new(); let mut existing_file_path = data_path.clone(); existing_file_path.push("existing_among_us_dir.txt"); @@ -203,7 +183,7 @@ async fn main() { .launch(data) .unwrap_or_default(); - among_us_folder = path::PathBuf::from(Rc::try_unwrap(path_rc).unwrap().take()); + among_us_folder = PathBuf::from(Rc::try_unwrap(path_rc).unwrap().take()); println!("{}", among_us_folder.to_str().unwrap()); @@ -232,19 +212,18 @@ async fn main() { among_us_version.to_string().clone(), ver_url.0.clone() ); - let new_installed_path: path::PathBuf = - [installs_path.to_str().unwrap(), version_smash.as_str()] - .iter() - .collect(); + let new_installed_path: PathBuf = [installs_path.to_str().unwrap(), version_smash.as_str()] + .iter() + .collect(); - if !path::Path::exists(&new_installed_path) { + if !Path::exists(&new_installed_path) { println!("Copying Among Us to separate location..."); copy_folder_to_target( among_us_folder.to_str().unwrap(), installs_path.to_str().unwrap(), ); - let among_us_path: path::PathBuf = [installs_path.to_str().unwrap(), "Among Us\\"] + let among_us_path: PathBuf = [installs_path.to_str().unwrap(), "Among Us\\"] .iter() .collect(); @@ -270,7 +249,7 @@ async fn main() { let downloaded_filename = ver_url.1.rsplit("/").nth(0).unwrap(); download_path.push(downloaded_filename.clone()); - if !path::Path::exists(&download_path) { + if !Path::exists(&download_path) { // println!("{:?}", download_path); println!("Downloading Town of Us... [{}]", ver_url.1.clone()); let zip = reqwest::get(ver_url.1.clone()) @@ -292,10 +271,9 @@ async fn main() { root_folder_path = String::from(i.split("/").nth(0).unwrap()); break; } - let extracted_path: path::PathBuf = - [data_path.to_str().unwrap(), root_folder_path.as_str(), "."] - .iter() - .collect(); + let extracted_path: PathBuf = [data_path.to_str().unwrap(), root_folder_path.as_str(), "."] + .iter() + .collect(); println!("{}", extracted_path.to_str().unwrap()); copy_folder_contents_to_target( extracted_path.to_str().unwrap(), @@ -310,7 +288,7 @@ async fn main() { let mut root_column: druid::widget::Flex = druid::widget::Flex::column(); if let Ok(iter) = install_iter { - let mut collection: Vec> = iter.collect(); + let mut collection: Vec> = iter.collect(); collection.reverse(); // Iterate first to find labels: @@ -392,7 +370,7 @@ async fn main() { // .iter() // .collect(); - // std::process::Command::new(executable_path.to_str().unwrap()) + // process::Command::new(executable_path.to_str().unwrap()) // .spawn() // .unwrap(); } @@ -506,7 +484,7 @@ fn determine_among_us_version(folder_root: String) -> Option { // )) } -fn copy_folder_to_target>(source: T, dest: T) { +fn copy_folder_to_target>(source: T, dest: T) { let mut copy_opts = dir::CopyOptions::new(); copy_opts.overwrite = true; copy_opts.skip_exist = true; @@ -516,7 +494,7 @@ fn copy_folder_to_target>(source: T, dest: T) { copy_items(&from_paths, dest, ©_opts).unwrap(); } -fn copy_folder_contents_to_target>(source: T, dest: T) { +fn copy_folder_contents_to_target>(source: T, dest: T) { let mut copy_opts = dir::CopyOptions::new(); copy_opts.overwrite = true; copy_opts.skip_exist = true; From 9564c70a333479b9ef4757cf44c19502054cc354 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Mon, 29 Aug 2022 19:17:47 -0700 Subject: [PATCH 2/6] Remove comments, simplify --- src/main.rs | 40 +++------------------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/src/main.rs b/src/main.rs index d44a2ab..3860f26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -202,6 +202,7 @@ async fn main() { let among_us_version = determine_among_us_version(String::from(among_us_folder.to_str().unwrap())).unwrap(); + println!("AmongUsVersion: {}", among_us_version); let ver_url: (String, String, bool) = determine_town_of_us_url(among_us_version.to_string().clone()) .await @@ -394,23 +395,6 @@ async fn determine_town_of_us_url(among_us_version: String) -> Option<(String, S println!("Sanctioned version cannot be determined, installing experimental latest..."); line = markdown.find("[Download]"); line_offset = 15; - // println!("At this point, there are two options:"); - // println!(" [1] Revert Among Us to public-previous in Steam THEN select this option."); - // println!(" [2] Attempt to use the latest version of Town of Us anyway"); - // let mut input = String::new(); - // io::stdin().read_line(&mut input).unwrap(); - // match input.trim() { - // "1" => { - // println!("Re-attempting..."); - // return None; - // } - // "2" => { - // println!("Continuing..."); - // line = markdown.find("[Download]"); - // line_offset = 15; - // } - // _ => return None, - // }; } // 100% scientific "-15" here to get the correct version since we find to [Download] above which is after the version number for that line let splits = markdown.split_at(line.unwrap() - line_offset); @@ -461,27 +445,9 @@ fn determine_among_us_version(folder_root: String) -> Option { let offset: usize = usize::from(file_bytes[file_index]); file_index += 4; - // let mut offset = 10; - - // if file_bytes[file_index + 9] == 0 { - // offset -= 1; - // } - // if file_bytes[file_index + 8] == 0 { - // offset -= 1; - // } - - // println!( - // "|{}|", - // str::from_utf8(file_bytes.get(file_index..file_index + offset).unwrap()).unwrap() - // ); - let ver = AmongUsVersion::from( + Some(AmongUsVersion::from( str::from_utf8(file_bytes.get(file_index..file_index + offset).unwrap()).unwrap(), - ); - println!("AmongUsVersion: {}", ver); - Some(ver) - // Some(String::from( - // str::from_utf8(file_bytes.get(file_index..file_index + offset).unwrap()).unwrap(), - // )) + )) } fn copy_folder_to_target>(source: T, dest: T) { From bac49bc7664ac7fee28b698934af15e3b67e8977 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Mon, 29 Aug 2022 22:59:19 -0700 Subject: [PATCH 3/6] Fix clippy compile error --- src/main.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3860f26..4375291 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ struct AppData { pub among_us_path: Rc>, } -static AMONG_US_APPID: &'static str = "945360"; +static AMONG_US_APPID: &str = "945360"; fn attempt_run_among_us(install_path: &Path) { let executable_path: PathBuf = [install_path.to_str().unwrap(), "Among Us.exe"] @@ -320,8 +320,7 @@ async fn main() { let auv = ver_smash_split.next().unwrap(); let button_string: String = format!("Town of Us {}", ver_smash_split.next().unwrap()); - let mut index = 0; - for j in &auv_array { + for (index, j) in auv_array.iter().enumerate() { if j == auv { let mut clone = installs_path.clone(); clone.push(existing_ver_smash.clone()); @@ -339,7 +338,6 @@ async fn main() { println!("{}", existing_ver_smash.clone().to_str().unwrap()); } - index += 1; } } for i in flexbox_array { From 35828e4b5b6fa3d8e045ad2f2f288d1db4350a11 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Mon, 29 Aug 2022 22:59:53 -0700 Subject: [PATCH 4/6] Clippy fixes --- src/among_us_version.rs | 2 +- src/main.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/among_us_version.rs b/src/among_us_version.rs index 82473e8..c395e4a 100644 --- a/src/among_us_version.rs +++ b/src/among_us_version.rs @@ -17,7 +17,7 @@ impl From<&str> for AmongUsVersion { // Ignore a prepending "v" let tmp_str = s.replace("v", ""); - let v: Vec<&str> = tmp_str.split(".").collect(); + let v: Vec<&str> = tmp_str.split('.').collect(); AmongUsVersion { year: i32::from_str_radix(v[0], 10).unwrap(), diff --git a/src/main.rs b/src/main.rs index 4375291..bcad756 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,7 +210,7 @@ async fn main() { let version_smash = format!( "{}-{}", - among_us_version.to_string().clone(), + among_us_version, ver_url.0.clone() ); let new_installed_path: PathBuf = [installs_path.to_str().unwrap(), version_smash.as_str()] @@ -247,7 +247,7 @@ async fn main() { fs::rename(among_us_path, new_installed_path.clone()).unwrap(); let mut download_path = data_path.clone(); - let downloaded_filename = ver_url.1.rsplit("/").nth(0).unwrap(); + let downloaded_filename = ver_url.1.rsplit('/').next().unwrap(); download_path.push(downloaded_filename.clone()); if !Path::exists(&download_path) { @@ -269,7 +269,7 @@ async fn main() { let mut root_folder_path = String::new(); for i in archive.file_names() { - root_folder_path = String::from(i.split("/").nth(0).unwrap()); + root_folder_path = String::from(i.split('/').next().unwrap()); break; } let extracted_path: PathBuf = [data_path.to_str().unwrap(), root_folder_path.as_str(), "."] @@ -299,7 +299,7 @@ async fn main() { for i in &collection { let existing_ver_smash = i.as_ref().unwrap().file_name(); - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split("-"); + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); let auv = ver_smash_split.next().unwrap(); if !auv_array.contains(&auv.to_string()) { let label_text = format!("Among Us {}", auv); @@ -316,7 +316,7 @@ async fn main() { for i in collection { let existing_ver_smash = i.unwrap().file_name(); - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split("-"); + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); let auv = ver_smash_split.next().unwrap(); let button_string: String = format!("Town of Us {}", ver_smash_split.next().unwrap()); From cf75410860384fa00d7b345cae0c9b9588b62093 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Mon, 29 Aug 2022 23:30:29 -0700 Subject: [PATCH 5/6] Clippy fixes --- src/among_us_version.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/among_us_version.rs b/src/among_us_version.rs index c395e4a..0383474 100644 --- a/src/among_us_version.rs +++ b/src/among_us_version.rs @@ -1,4 +1,5 @@ use std::fmt; + #[derive(Ord, PartialOrd, Eq, PartialEq)] pub struct AmongUsVersion { year: i32, @@ -20,9 +21,9 @@ impl From<&str> for AmongUsVersion { let v: Vec<&str> = tmp_str.split('.').collect(); AmongUsVersion { - year: i32::from_str_radix(v[0], 10).unwrap(), - month: i32::from_str_radix(v[1], 10).unwrap(), - day: i32::from_str_radix(v[2], 10).unwrap(), + year: v[0].parse().unwrap(), + month: v[1].parse().unwrap(), + day: v[2].parse().unwrap(), } } } From e59c25af25a84bdb2b3b2bc92f32eb5f93446d08 Mon Sep 17 00:00:00 2001 From: Ian Mason Date: Wed, 31 Aug 2022 12:51:56 -0700 Subject: [PATCH 6/6] Cleaned up dead code comments Locating the among us folder and launching the app are one in the same, need GUI work to allow it to update after location More and changed log messages --- src/main.rs | 364 ++++++++++++++++++++++++++++------------------------ 1 file changed, 193 insertions(+), 171 deletions(-) diff --git a/src/main.rs b/src/main.rs index bcad756..1637d77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ struct Delegate; #[derive(Data, Clone)] struct AppData { pub among_us_path: Rc>, + pub installs_path: String, } static AMONG_US_APPID: &str = "945360"; @@ -36,6 +37,7 @@ fn attempt_run_among_us(install_path: &Path) { } fn unmod_among_us_folder(folder_path: &Path) { + println!("Unmodding Among Us..."); let doorstop_path: PathBuf = [folder_path.to_str().unwrap(), "doorstop_config.ini"] .iter() .collect(); @@ -45,6 +47,7 @@ fn unmod_among_us_folder(folder_path: &Path) { let winhttp_path: PathBuf = [folder_path.to_str().unwrap(), "winhttp.dll"] .iter() .collect(); + let bepinex_path: PathBuf = [folder_path.to_str().unwrap(), "BepInEx"].iter().collect(); let mono_path: PathBuf = [folder_path.to_str().unwrap(), "mono"].iter().collect(); fs::remove_file(doorstop_path).unwrap_or_default(); @@ -124,6 +127,7 @@ impl AppDelegate for Delegate { println!("{}", buf.to_str().unwrap()); println!("Handled!"); Application::global().quit(); + return Handled::Yes; } Handled::No @@ -137,7 +141,6 @@ async fn main() { println!("Updater Version: {}", version); get_latest_updater_version().await.unwrap(); - //let _version_check_thread_handle = thread::spawn(move || get_latest_updater_version()); // CREATE PROGRAM DIRECTORY let mut data_path = dirs::data_dir().unwrap(); @@ -148,6 +151,13 @@ async fn main() { installs_path.push("installs"); fs::create_dir(installs_path.clone()).unwrap_or(()); + let app_data: AppData = AppData { + among_us_path: Rc::new(RefCell::new(String::from(""))), + installs_path: String::from(""), + }; + + let mut root_column: druid::widget::Flex = druid::widget::Flex::column(); + // DETERMINE AMONG US VERSION let mut among_us_folder = PathBuf::new(); @@ -156,17 +166,13 @@ async fn main() { existing_file_path.push("existing_among_us_dir.txt"); let existing_found_folder = fs::read_to_string(existing_file_path.clone()); - if existing_found_folder.is_ok() { - among_us_folder.push(existing_found_folder.unwrap()); + if let Ok(existing_folder) = existing_found_folder { + among_us_folder.push(existing_folder); } else { let folder_opt = detect_among_us_folder(); if folder_opt.is_some() { among_us_folder.push(folder_opt.unwrap()); } else { - let path_rc = Rc::new(RefCell::new(String::from(""))); - let data: AppData = AppData { - among_us_path: path_rc.clone(), - }; let open_button = Button::new("Locate Among Us").fix_height(45.0).on_click( move |ctx, _: &mut AppData, _| { ctx.submit_command( @@ -174,180 +180,194 @@ async fn main() { ); }, ); - let flex: Flex = Flex::column().with_flex_child(open_button, 1.0); - let open_dialog = WindowDesc::new(|| flex) - .title("Among Us Not Found!") - .window_size((400.0, 400.0)); - AppLauncher::with_window(open_dialog) - .delegate(Delegate) - .launch(data) - .unwrap_or_default(); - among_us_folder = PathBuf::from(Rc::try_unwrap(path_rc).unwrap().take()); + // If we can't find Among Us, add the locate button. + // TODO: make this button then update the UI assuming it's valid - println!("{}", among_us_folder.to_str().unwrap()); - - // win.modal_msg(&ui, "Find Among Us", "On the following Open File dialog, navigate to your Among Us folder and select Among Us.exe"); - // let open_window = win.open_file(&ui); - // println!("{}", open_window.unwrap().to_str().unwrap()); - // among_us_folder = open_window.unwrap().clone(); + root_column.add_flex_child(open_button, 1.0); // Pop the selected file off the end of the path // among_us_folder.pop(); } - fs::write(existing_file_path, among_us_folder.to_str().unwrap()).unwrap(); + + if among_us_folder.exists() { + fs::write(existing_file_path, among_us_folder.to_str().unwrap()).unwrap(); + } } - println!("Among Us Folder: {}", among_us_folder.to_str().unwrap()); - - let among_us_version = - determine_among_us_version(String::from(among_us_folder.to_str().unwrap())).unwrap(); - println!("AmongUsVersion: {}", among_us_version); - let ver_url: (String, String, bool) = - determine_town_of_us_url(among_us_version.to_string().clone()) - .await - .unwrap(); - - let version_smash = format!( - "{}-{}", - among_us_version, - ver_url.0.clone() - ); - let new_installed_path: PathBuf = [installs_path.to_str().unwrap(), version_smash.as_str()] - .iter() - .collect(); - - if !Path::exists(&new_installed_path) { - println!("Copying Among Us to separate location..."); - copy_folder_to_target( - among_us_folder.to_str().unwrap(), - installs_path.to_str().unwrap(), - ); - - let among_us_path: PathBuf = [installs_path.to_str().unwrap(), "Among Us\\"] - .iter() - .collect(); - - if !among_us_path.to_str().unwrap().contains("Among Us") { - process::exit(0); + if let Some(among_us_folder_str) = among_us_folder.to_str() { + if among_us_folder_str.len() > 0 { + println!("Among Us Folder: {}", among_us_folder_str); + } else { + println!("Among Us Folder not automatically determined"); } + } - // 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 = data_path.clone(); - let downloaded_filename = ver_url.1.rsplit('/').next().unwrap(); - download_path.push(downloaded_filename.clone()); - - if !Path::exists(&download_path) { - // println!("{:?}", download_path); - println!("Downloading Town of Us... [{}]", ver_url.1.clone()); - let zip = reqwest::get(ver_url.1.clone()) - .await - .unwrap() - .bytes() + if let Some(among_us_version) = + determine_among_us_version(String::from(among_us_folder.to_str().unwrap())) + { + println!("AmongUsVersion: {}", among_us_version); + let ver_url: (String, String, bool) = + determine_town_of_us_url(among_us_version.to_string().clone()) .await .unwrap(); - fs::write(download_path.clone(), zip).unwrap(); - } - let opened_zip = fs::File::open(download_path).unwrap(); - println!("Extracting..."); - let mut archive = zip::ZipArchive::new(opened_zip).unwrap(); - archive.extract(data_path.clone()).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.to_str().unwrap(), root_folder_path.as_str(), "."] + let version_smash = format!("{}-{}", among_us_version, ver_url.0.clone()); + let new_installed_path: PathBuf = [installs_path.to_str().unwrap(), version_smash.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(), - ); - } else { - println!("Modded install already found"); - } - // Find existing installs, make buttons for them - let install_iter = fs::read_dir(installs_path.clone()); - let mut root_column: druid::widget::Flex = druid::widget::Flex::column(); + if !Path::exists(&new_installed_path) { + println!("Copying Among Us to cache location..."); + copy_folder_to_target( + among_us_folder.to_str().unwrap(), + installs_path.to_str().unwrap(), + ); - if let Ok(iter) = install_iter { - let mut collection: Vec> = iter.collect(); - collection.reverse(); + let among_us_path: PathBuf = [installs_path.to_str().unwrap(), "Among Us\\"] + .iter() + .collect(); - // Iterate first to find labels: - - let mut flexbox_array: Vec> = Vec::new(); - let mut auv_array: Vec = Vec::new(); - - for i in &collection { - let existing_ver_smash = i.as_ref().unwrap().file_name(); - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); - let auv = ver_smash_split.next().unwrap(); - if !auv_array.contains(&auv.to_string()) { - let label_text = format!("Among Us {}", auv); - let flex: druid::widget::Flex = druid::widget::Flex::column() - .with_flex_child( - druid::widget::Label::new(label_text.as_str()).with_text_size(24.0), - 1.0, - ) - .with_default_spacer(); - flexbox_array.push(flex); - auv_array.push(auv.to_string()); + 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 = data_path.clone(); + let downloaded_filename = ver_url.1.rsplit('/').next().unwrap(); + download_path.push(downloaded_filename.clone()); + + if !Path::exists(&download_path) { + // println!("{:?}", download_path); + println!("Downloading Town of Us... [{}]", ver_url.1.clone()); + let zip = reqwest::get(ver_url.1.clone()) + .await + .unwrap() + .bytes() + .await + .unwrap(); + fs::write(download_path.clone(), zip).unwrap(); + } + + let opened_zip = fs::File::open(download_path).unwrap(); + println!("Extracting mod zip file..."); + let mut archive = zip::ZipArchive::new(opened_zip).unwrap(); + archive.extract(data_path.clone()).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.to_str().unwrap(), 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(), + ); + } else { + println!("Modded install already found"); } - for i in collection { - let existing_ver_smash = i.unwrap().file_name(); - let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); - let auv = ver_smash_split.next().unwrap(); - let button_string: String = format!("Town of Us {}", ver_smash_split.next().unwrap()); + // Find existing installs, make buttons for them + let install_iter = fs::read_dir(installs_path.clone()); - for (index, j) in auv_array.iter().enumerate() { - if j == auv { - let mut clone = installs_path.clone(); - clone.push(existing_ver_smash.clone()); + if let Ok(iter) = install_iter { + let mut collection: Vec> = iter.collect(); + collection.reverse(); - let fybutton = druid::widget::Button::new(button_string.as_str()) - .fix_height(45.0) - .on_click(move |_, _: &mut u32, _| { - attempt_run_among_us(&clone); - }); + // Iterate first to find labels: - flexbox_array - .get_mut(index) - .unwrap() - .add_flex_child(fybutton, 1.0); + let mut flexbox_array: Vec> = Vec::new(); + let mut auv_array: Vec = Vec::new(); - println!("{}", existing_ver_smash.clone().to_str().unwrap()); + for i in &collection { + let existing_ver_smash = i.as_ref().unwrap().file_name(); + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); + let auv = ver_smash_split.next().unwrap(); + if !auv_array.contains(&auv.to_string()) { + let label_text = format!("Among Us {}", auv); + let flex: druid::widget::Flex = druid::widget::Flex::column() + .with_flex_child( + druid::widget::Label::new(label_text.as_str()).with_text_size(24.0), + 1.0, + ) + .with_default_spacer(); + flexbox_array.push(flex); + auv_array.push(auv.to_string()); } } - } - for i in flexbox_array { - root_column.add_flex_child(i, 1.0); + + println!("Installs list:"); + + for i in collection { + let existing_ver_smash = i.unwrap().file_name(); + let mut ver_smash_split = existing_ver_smash.to_str().unwrap().split('-'); + let auv = ver_smash_split.next().unwrap(); + let button_string: String = + format!("Town of Us {}", ver_smash_split.next().unwrap()); + + for (index, j) in auv_array.iter().enumerate() { + if j == auv { + let mut clone = installs_path.clone(); + clone.push(existing_ver_smash.clone()); + + let mut button_row: Flex = Flex::row(); + + let fybutton = druid::widget::Button::new(button_string.as_str()) + .fix_height(45.0) + .center() + .on_click(move |_, _: &mut AppData, _| { + attempt_run_among_us(&clone); + }); + + button_row.add_flex_child(fybutton, 1.0); + + // TODO: Uncomment + // let delete_button = druid::widget::Button::new("Delete") + // .fix_height(45.0) + // .on_click(move |_, _: &mut AppData, _| {}); + + // button_row.add_flex_child(delete_button, 1.0); + + flexbox_array + .get_mut(index) + .unwrap() + .add_flex_child(button_row, 1.0); + + println!("- {}", existing_ver_smash.clone().to_str().unwrap()); + } + } + } + + for i in flexbox_array { + root_column.add_flex_child(i, 1.0); + } } } // println!("Checking for updater updates..."); // let vals: (String, String) = version_check_thread_handle.join().unwrap(); + // TODO: Auto launch latest sanctioned if the user has a setting like that + // Auto launch latest experimental as well + println!("Launching main window..."); let main_window = WindowDesc::new(|| root_column) @@ -355,8 +375,7 @@ async fn main() { .window_size((400.0, 400.0)); let app_launcher = AppLauncher::with_window(main_window); let _external_handler = app_launcher.get_external_handle(); - app_launcher.launch(1).unwrap(); - // AppLauncher::with_window(main_window).launch(1).unwrap(); + app_launcher.launch(app_data).unwrap(); // let mut install_folder_path = installs_path.clone(); // install_folder_path.push(version_smash); @@ -420,32 +439,35 @@ fn determine_among_us_version(folder_root: String) -> Option { let target_bytes: [u8; TARGET_BYTES_LEN] = [3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0]; - let file_bytes = fs::read(asset_file).unwrap(); - //println!("{:?}", file_bytes); + if let Ok(file_bytes) = fs::read(asset_file) { + let mut bytes_str = String::new(); + let mut target_head = 0; + let mut file_index = 0; + for i in &file_bytes { + if target_head == TARGET_BYTES_LEN { + break; + } - let mut bytes_str = String::new(); - let mut target_head = 0; - let mut file_index = 0; - for i in &file_bytes { - if target_head == TARGET_BYTES_LEN { - break; + if *i == target_bytes[target_head] { + target_head += 1; + } else { + target_head = 0; + } + file_index += 1; + bytes_str += &format!("{i:x}"); } - if *i == target_bytes[target_head] { - target_head += 1; - } else { - target_head = 0; - } - file_index += 1; - bytes_str += &format!("{i:x}"); + let offset: usize = usize::from(file_bytes[file_index]); + file_index += 4; + + Some(AmongUsVersion::from( + str::from_utf8(file_bytes.get(file_index..file_index + offset).unwrap()).unwrap(), + )) + } else { + None } - let offset: usize = usize::from(file_bytes[file_index]); - file_index += 4; - - Some(AmongUsVersion::from( - str::from_utf8(file_bytes.get(file_index..file_index + offset).unwrap()).unwrap(), - )) + //println!("{:?}", file_bytes); } fn copy_folder_to_target>(source: T, dest: T) {