Add support to decompress files in paz file

This commit is contained in:
2025-11-03 11:20:49 +08:00
parent f363a8a24a
commit 9da81ddfaa
2 changed files with 24 additions and 1 deletions

View File

@@ -91,7 +91,7 @@ kirikiri = ["emote-psb", "fancy-regex", "flate2", "json", "lz4", "utils-escape"]
kirikiri-arc = ["kirikiri", "adler", "fastcdc", "flate2", "parse-size", "sha2", "xp3", "zstd"] kirikiri-arc = ["kirikiri", "adler", "fastcdc", "flate2", "parse-size", "sha2", "xp3", "zstd"]
kirikiri-img = ["kirikiri", "image", "libtlg-rs"] kirikiri-img = ["kirikiri", "image", "libtlg-rs"]
musica = [] musica = []
musica-arc = ["musica", "crc32fast", "include-flate", "utils-blowfish", "utils-rc4", "utils-serde-base64bytes", "utils-xored-stream"] musica-arc = ["musica", "crc32fast", "flate2", "include-flate", "utils-blowfish", "utils-rc4", "utils-serde-base64bytes", "utils-xored-stream"]
silky = [] silky = []
softpal = ["int-enum"] softpal = ["int-enum"]
softpal-arc = ["softpal"] softpal-arc = ["softpal"]

View File

@@ -8,6 +8,7 @@ use crate::utils::serde_base64bytes::Base64Bytes;
use crate::utils::struct_pack::*; use crate::utils::struct_pack::*;
use crate::utils::xored_stream::*; use crate::utils::xored_stream::*;
use anyhow::Result; use anyhow::Result;
use flate2::read::ZlibDecoder;
use msg_tool_macro::{StructPack, StructUnpack}; use msg_tool_macro::{StructPack, StructUnpack};
use serde::Deserialize; use serde::Deserialize;
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
@@ -192,6 +193,12 @@ struct PazEntry {
flags: u32, flags: u32,
} }
impl PazEntry {
pub fn is_compressed(&self) -> bool {
(self.flags & 0x1) != 0
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct PazArc { pub struct PazArc {
stream: Arc<Mutex<MultipleReadStream>>, stream: Arc<Mutex<MultipleReadStream>>,
@@ -386,13 +393,25 @@ impl Script for PazArc {
rc4.skip_bytes(skip as usize); rc4.skip_bytes(skip as usize);
} }
let stream = Rc4Stream::new(stream, rc4); let stream = Rc4Stream::new(stream, rc4);
if entry.is_compressed() {
let stream = ZlibDecoder::new(stream);
return Ok(Box::new(PazFileEntry::new(entry, stream)));
}
return Ok(Box::new(PazFileEntry::new(entry, stream))); return Ok(Box::new(PazFileEntry::new(entry, stream)));
} }
} }
if entry.is_compressed() {
let stream = ZlibDecoder::new(stream);
return Ok(Box::new(PazFileEntry::new(entry, stream)));
}
return Ok(Box::new(PazFileEntry::new(entry, stream))); return Ok(Box::new(PazFileEntry::new(entry, stream)));
} else if let Some(mov_key) = &self.mov_key { } else if let Some(mov_key) = &self.mov_key {
if self.schema.version < 1 { if self.schema.version < 1 {
let stream = TableEncryptedStream::new(stream, mov_key.clone())?; let stream = TableEncryptedStream::new(stream, mov_key.clone())?;
if entry.is_compressed() {
let stream = ZlibDecoder::new(stream);
return Ok(Box::new(PazFileEntry::new(entry, stream)));
}
return Ok(Box::new(PazFileEntry::new(entry, stream))); return Ok(Box::new(PazFileEntry::new(entry, stream)));
} }
let type_key = self let type_key = self
@@ -416,6 +435,10 @@ impl Script for PazArc {
let mut rc4 = Rc4::new(&rkey); let mut rc4 = Rc4::new(&rkey);
let key_block = rc4.generate_block((entry.size as usize).min(0x10000)); let key_block = rc4.generate_block((entry.size as usize).min(0x10000));
let stream = XoredKeyStream::new(stream, key_block, 0); let stream = XoredKeyStream::new(stream, key_block, 0);
if entry.is_compressed() {
let stream = ZlibDecoder::new(stream);
return Ok(Box::new(PazFileEntry::new(entry, stream)));
}
return Ok(Box::new(PazFileEntry::new(entry, stream))); return Ok(Box::new(PazFileEntry::new(entry, stream)));
} }
Err(anyhow::anyhow!("Data decryption key not found.")) Err(anyhow::anyhow!("Data decryption key not found."))