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) {