Skip to content

Commit 282a205

Browse files
Work on CC unpacking logic
1 parent c162ff6 commit 282a205

File tree

1 file changed

+98
-7
lines changed

1 file changed

+98
-7
lines changed

src/cold_clear.rs

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
use std::ffi::{OsStr, OsString};
12
use std::io::Write;
3+
use std::fs::{self, File};
4+
use std::path::{PathBuf};
5+
use std::collections::HashMap;
26
use std::thread;
37
use std::time::{Instant, Duration};
48
use std::sync::{mpsc, Arc, Mutex};
@@ -312,19 +316,106 @@ fn get_path_score(path: &str) -> i8 {
312316
}
313317
}
314318

319+
fn pick_files_to_move(path: &PathBuf) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
320+
// Traverse through the directories and pick files for flattenning
321+
// If identical filename, choose one with higher path score
322+
let path = path.to_path_buf();
323+
324+
fn traverse(path: PathBuf) -> Result<Vec<PathBuf>, std::io::Error> {
325+
let entries = path.as_path().read_dir()?;
326+
327+
let mut file_list: Vec<PathBuf> = Vec::new();
328+
329+
for entry in entries {
330+
let entry = entry?;
331+
332+
if entry.file_type()?.is_dir() {
333+
file_list.append(&mut traverse(entry.path())?);
334+
continue;
335+
}
336+
337+
file_list.push(entry.path());
338+
}
339+
340+
return Ok(file_list);
341+
}
342+
343+
let file_list = traverse(path)?;
344+
345+
let mut file_map: HashMap<OsString, PathBuf> = HashMap::new();
346+
347+
for path in file_list {
348+
let name = path.file_name();
349+
350+
if name.is_none() {
351+
return Err(
352+
format!("Failed to get filename for file: {:#?}", path).into()
353+
);
354+
}
355+
356+
let name = name.unwrap();
357+
358+
if file_map.contains_key(name) {
359+
let other_path = file_map.get(name).unwrap();
360+
361+
let path_str = path.to_str();
362+
let other_path_str = other_path.to_str();
363+
364+
if path_str.is_none() {
365+
return Err(
366+
format!("Failed to get UTF-8 path string for path: {:#?}", path).into()
367+
);
368+
}
369+
370+
if other_path_str.is_none() {
371+
return Err(
372+
format!("Failed to get UTF-8 path string for path: {:#?}", path).into()
373+
);
374+
}
375+
376+
let cur_score = get_path_score(path_str.unwrap());
377+
let other_score = get_path_score(other_path_str.unwrap());
378+
379+
if cur_score > other_score {
380+
file_map.insert(name.into(), path.to_owned());
381+
}
382+
} else {
383+
file_map.insert(name.into(), path.to_owned());
384+
}
385+
}
386+
387+
return Ok(
388+
file_map
389+
.values()
390+
.cloned()
391+
.collect()
392+
);
393+
}
394+
315395
pub fn unpack_cold_clear(version: &str) -> Result<(), Box<dyn std::error::Error>> {
316-
let save_path = paths::get_cold_clear_download_path(version);
317-
let save_path = save_path.as_path();
396+
let zip_path = paths::get_cold_clear_download_path(version);
397+
let zip_path = zip_path.as_path();
318398

319-
if !save_path.exists() {
399+
if !zip_path.exists() {
320400
download_cold_clear(version)?;
321401
}
322402

323-
let save_path = save_path.to_str().unwrap();
403+
let zip_file = std::fs::File::open(zip_path)?;
404+
let mut zip_archive = ZipArchive::new(&zip_file)?;
405+
406+
let lib_path = paths::get_sandboxed_save_path().join("lib");
407+
let temp_lib_path = paths::get_sandboxed_save_path().join("~lib");
324408

325-
let zip_file = std::fs::File::open(save_path)?;
409+
zip_archive.extract(&temp_lib_path)?;
326410

327-
let mut zip_archive = ZipArchive::new(zip_file)?;
411+
let files_to_move = pick_files_to_move(&temp_lib_path)?;
412+
413+
for path in files_to_move {
414+
let dest = lib_path.join(path.file_name().unwrap());
415+
fs::rename(path, dest)?;
416+
}
328417

329-
todo!(); // TODO: Extract, flatten, select (path_score) and move library files
418+
fs::remove_dir_all(temp_lib_path)?;
419+
420+
return Ok(());
330421
}

0 commit comments

Comments
 (0)