wormhole_common/installer/
bepinex.rs1use zip::ZipArchive;
2
3use crate::downloader::Downloader;
4use std::{
5 fs::{self, File},
6 path::PathBuf,
7};
8
9pub struct BepInExInstallManager {
10 pub ksp2_install_path: PathBuf,
11 pub zip_url: String,
12}
13
14impl BepInExInstallManager {
15 pub fn new(ksp2_install_path: PathBuf) -> Self {
16 return BepInExInstallManager {
17 ksp2_install_path,
18
19 zip_url: "https://github.com/BepInEx/BepInEx/releases/download/v5.4.21/BepInEx_x64_5.4.21.0.zip".to_string(),
24 };
25 }
26
27 pub async fn download<W>(
28 &mut self,
29 on_progress: fn(u64, usize, W) -> (),
30 on_finish: fn(u64, W) -> (),
31 window: W,
32 ) -> Result<(), String>
33 where
34 W: Clone,
35 {
36 if !self.ksp2_install_path.is_dir() {
37 return Err("KSP2 install path is not a directory!".to_string());
38 }
39
40 let files_in_dir = self.ksp2_install_path.read_dir().unwrap();
41
42 for file in files_in_dir {
43 let file = file.unwrap();
44 let file_name = file.file_name().into_string().unwrap();
45
46 if file_name.contains("doorstop_config.ini")
47 || file_name.contains(".doorstop_version")
48 || file_name.contains("winhttp.dll")
49 || file_name.contains("version.dll")
50 || file_name.contains("BepInEx")
51 {
52 return Err("BepInEx or another mod loader is already installed!".to_string());
53 }
54 }
55
56 let download_url = self.zip_url.clone();
57
58 println!("Downloading from URL: {}", download_url);
59
60 let out_file = self.ksp2_install_path.join(".bepinex_release.zip");
61
62 Downloader::download(
63 download_url,
64 out_file.clone(),
65 on_progress,
66 on_finish,
67 window,
68 )
69 .await;
70
71 let mut zip = ZipArchive::new(File::open(out_file.clone()).unwrap()).unwrap();
72
73 zip.extract(self.ksp2_install_path.clone())
74 .expect("Could not extract the BepInEx release!");
75
76 fs::remove_file(out_file).expect("Could not delete the BepInEx release file!");
77
78 return Ok(());
79 }
80}