use super::*;
impl LpkLoader {
pub(crate) fn extract_standard<P: AsRef<Path>>(&mut self, output_dir: P) -> Result<()> {
let output_dir = output_dir.as_ref();
let mut extraction_tasks = Vec::new();
for chara in self.mlve_config.list.as_slice() {
let chara_name = match chara.character.as_str() {
"" => "character",
name => name,
};
let subdir = output_dir.join(&chara_name);
safe_mkdir(&subdir)?;
for (i, costume) in chara.costume.iter().enumerate() {
let path = costume.path.as_str();
if !path.is_empty() {
extraction_tasks.push((path.to_string(), subdir.clone(), format!("{}_costume_{}", chara_name, i)));
}
}
}
for (path, subdir, costume_name) in extraction_tasks {
info!("extracting {}", costume_name);
self.extract_costume(&path, &subdir)?;
}
for chara in self.mlve_config.list.as_slice() {
let chara_name = match chara.character.as_str() {
"" => "character",
name => name,
};
let subdir = output_dir.join(chara_name);
for (name, content) in &self.entrys {
let mut out_s = content.clone();
for (k, v) in &self.uncompressed {
out_s = out_s.replace(k, v);
}
let output_file = subdir.join(name);
let mut file = File::create(output_file)?;
file.write_all(out_s.as_bytes())?;
}
}
Ok(())
}
}
impl LpkLoader {
pub(crate) fn extract_legacy<P: AsRef<Path>>(&mut self, output_dir: P) -> Result<()> {
let output_dir = output_dir.as_ref();
warn!("Deprecated/unknown lpk format detected. Attempting with STD_1_0 format...");
warn!("Decryption may not work for some packs, even though this script outputs all files.");
if !self.encrypted {
info!("lpk is not encrypted, extracting all files...");
let file = File::open(&self.lpk_path)?;
let mut archive = ZipArchive::new(file)?;
archive.extract(output_dir)?;
return Ok(());
}
let file = File::open(&self.lpk_path)?;
let mut archive = ZipArchive::new(file)?;
for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
let outpath = match file.enclosed_name() {
Some(path) => path.to_owned(),
None => continue,
};
if outpath.extension().is_none() {
continue;
}
let subdir = output_dir.join(outpath.parent().unwrap_or_else(|| Path::new("")).to_path_buf());
let output_file_path = subdir.join(outpath.file_name().unwrap());
safe_mkdir(&subdir)?;
let extension = outpath.extension().and_then(|s| s.to_str()).unwrap_or("");
if extension == "json" || extension == "mlve" || extension == "txt" {
info!("Extracting {} -> {}", outpath.display(), output_file_path.display());
let mut outfile = File::create(&output_file_path)?;
std::io::copy(&mut file, &mut outfile)?;
}
else {
info!("Decrypting {} -> {}", outpath.display(), output_file_path.display());
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
let decrypted_data = self.decrypt_data(outpath.to_str().unwrap_or(""), &buffer)?;
let mut outfile = File::create(&output_file_path)?;
outfile.write_all(&decrypted_data)?;
}
}
Ok(())
}
}