mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-22 20:04:20 +08:00
dref support load dpak from archive
This commit is contained in:
@@ -32,8 +32,11 @@ impl ScriptBuilder for DrefBuilder {
|
||||
encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(Dref::new(buf, encoding, filename, config)?))
|
||||
Ok(Box::new(Dref::new(
|
||||
buf, encoding, filename, config, archive,
|
||||
)?))
|
||||
}
|
||||
|
||||
fn extensions(&self) -> &'static [&'static str] {
|
||||
@@ -71,6 +74,16 @@ impl Dpak {
|
||||
Ok(Self { psb })
|
||||
}
|
||||
|
||||
pub fn load_from_data(data: &[u8]) -> Result<Self> {
|
||||
let mut psb = PsbReader::open_psb(MemReaderRef::new(data))
|
||||
.map_err(|e| anyhow::anyhow!("Failed to read PSB from DPAK data: {:?}", e))?;
|
||||
let psb = psb
|
||||
.load()
|
||||
.map_err(|e| anyhow::anyhow!("Failed to load PSB from DPAK data: {:?}", e))?;
|
||||
let psb = psb.to_psb_fixed();
|
||||
Ok(Self { psb })
|
||||
}
|
||||
|
||||
pub fn load_image(&self, name: &str) -> Result<(ImageData, Option<OffsetData>)> {
|
||||
let root = self.psb.root();
|
||||
let rid = root[name]
|
||||
@@ -149,12 +162,31 @@ impl DpakLoader {
|
||||
};
|
||||
dpak.load_image(filename)
|
||||
}
|
||||
|
||||
pub fn load_archives(&mut self, in_archives: &HashMap<String, Vec<u8>>) -> Result<()> {
|
||||
for (name, data) in in_archives.iter() {
|
||||
if !self.map.contains_key(name) {
|
||||
let dpak = Dpak::load_from_data(data)?;
|
||||
self.map.insert(name.clone(), dpak);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Dref {
|
||||
urls: Vec<Url>,
|
||||
dir: PathBuf,
|
||||
in_archives: HashMap<String, Vec<u8>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Dref {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Dref")
|
||||
.field("urls", &self.urls)
|
||||
.field("dir", &self.dir)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Dref {
|
||||
@@ -163,6 +195,7 @@ impl Dref {
|
||||
encoding: Encoding,
|
||||
filename: &str,
|
||||
_config: &ExtraConfig,
|
||||
archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Self> {
|
||||
let text = decode_with_bom_detect(encoding, &buf, true)?.0;
|
||||
let mut urls = Vec::new();
|
||||
@@ -190,7 +223,25 @@ impl Dref {
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Self { urls, dir })
|
||||
let mut in_archives = HashMap::new();
|
||||
if let Some(archive) = archive {
|
||||
if archive.is_archive() {
|
||||
for url in urls.iter() {
|
||||
let filename = url.domain().ok_or(anyhow::anyhow!(
|
||||
"Invalid URL in DREF file: {} (missing domain)",
|
||||
url
|
||||
))?;
|
||||
if let Ok(mut content) = archive.open_file_by_name(filename, true) {
|
||||
in_archives.insert(filename.to_string(), content.data()?);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Self {
|
||||
urls,
|
||||
dir,
|
||||
in_archives,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +260,7 @@ impl Script for Dref {
|
||||
|
||||
fn export_image(&self) -> Result<ImageData> {
|
||||
let mut loader = DpakLoader::default();
|
||||
loader.load_archives(&self.in_archives)?;
|
||||
let base_url = &self.urls[0];
|
||||
let dpak = base_url.domain().ok_or(anyhow::anyhow!(
|
||||
"Invalid URL in DREF file: {} (missing domain)",
|
||||
|
||||
@@ -32,6 +32,7 @@ impl ScriptBuilder for PImgBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(PImg::new(MemReader::new(buf), filename, config)?))
|
||||
}
|
||||
@@ -42,6 +43,7 @@ impl ScriptBuilder for PImgBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
if filename == "-" {
|
||||
let data = crate::utils::files::read_file(filename)?;
|
||||
@@ -60,6 +62,7 @@ impl ScriptBuilder for PImgBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(PImg::new(reader, filename, config)?))
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ impl ScriptBuilder for TlgImageBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(TlgImage::new(MemReader::new(data), config)?))
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ impl ScriptBuilder for KsBuilder {
|
||||
encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(KsScript::new(buf, encoding, config)?))
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ impl ScriptBuilder for MdfBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(Mdf::new(buf, filename)?))
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ impl ScriptBuilder for ScnScriptBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(ScnScript::new(
|
||||
MemReader::new(buf),
|
||||
@@ -46,6 +47,7 @@ impl ScriptBuilder for ScnScriptBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
if filename == "-" {
|
||||
let data = crate::utils::files::read_file(filename)?;
|
||||
@@ -68,6 +70,7 @@ impl ScriptBuilder for ScnScriptBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(ScnScript::new(reader, filename, config)?))
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ impl ScriptBuilder for SimpleCryptBuilder {
|
||||
_encoding: Encoding,
|
||||
_archive_encoding: Encoding,
|
||||
_config: &ExtraConfig,
|
||||
_archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>> {
|
||||
Ok(Box::new(SimpleCrypt::new(buf, filename)?))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user