diff --git a/src/scripts/kirikiri/archive/xp3.rs b/src/scripts/kirikiri/archive/xp3.rs index 6a88db3..074689c 100644 --- a/src/scripts/kirikiri/archive/xp3.rs +++ b/src/scripts/kirikiri/archive/xp3.rs @@ -210,6 +210,7 @@ impl Script for Xp3Archive { let mut header = [0u8; 16]; let header_len = entry.read(&mut header)?; entry.rewind()?; + entry.script_type = detect_script_type(entry.index.info().name(), &header, header_len); if self.decrypt_simple_crypt && header_len >= 5 && header[0] == 0xFE @@ -239,6 +240,33 @@ impl Script for Xp3Archive { } } +fn detect_script_type(filename: &str, buf: &[u8], buf_len: usize) -> Option { + #[cfg(feature = "kirikiri-img")] + if buf_len >= 11 && libtlg_rs::is_valid_tlg(buf) { + return Some(ScriptType::KirikiriTlg); + } + if buf_len >= 8 && (buf.starts_with(b"TJS/ns0\0") || buf.starts_with(b"TJS/4s0\0")) { + return Some(ScriptType::KirikiriTjsNs0); + } + if buf_len >= 8 && buf.starts_with(b"TJS2100\0") { + return Some(ScriptType::KirikiriTjs2); + } + let extension = std::path::Path::new(filename) + .extension() + .and_then(|s| s.to_str()) + .unwrap_or("") + .to_lowercase(); + match extension.as_str() { + "ks" => Some(ScriptType::Kirikiri), + "scn" => Some(ScriptType::KirikiriScn), + #[cfg(feature = "emote-img")] + "dref" => Some(ScriptType::EmoteDref), + #[cfg(feature = "emote-img")] + "pimg" => Some(ScriptType::EmotePimg), + _ => None, + } +} + #[derive(Debug)] struct Entry { reader: Arc>, @@ -246,6 +274,7 @@ struct Entry { cache: Option>>>, pos: u64, entries_pos: Vec, + script_type: Option, } impl Entry { @@ -266,6 +295,7 @@ impl Entry { cache: None, pos: 0, entries_pos, + script_type: None, } } } @@ -278,6 +308,10 @@ impl ArchiveContent for Entry { fn to_data<'a>(&'a mut self) -> Result> { Ok(Box::new(self)) } + + fn script_type(&self) -> Option<&ScriptType> { + self.script_type.as_ref() + } } impl Read for Entry {