Allow to speicfy custom file list path

This commit is contained in:
2026-04-11 14:57:55 +08:00
parent 9bd284b149
commit 2873780797
5 changed files with 30 additions and 9 deletions

View File

@@ -742,6 +742,11 @@ pub struct Arg {
/// Disable diff handle when exporting Emote PIMG images to PSD files.
/// If enabled, no group layers will be crated if both layer don't have diff_id and group_layer_id attribute.
pub emote_pimg_psd_no_diff: bool,
#[cfg(feature = "kirikiri-arc")]
#[arg(long, global = true)]
/// The path to the file list for Kirikiri XP3 archive. This is used to recover file names from hashed values.
/// Only works with some encyrption methods.
pub xp3_file_list_path: Option<String>,
#[command(subcommand)]
/// Command
pub command: Command,

View File

@@ -3401,6 +3401,8 @@ fn main() {
xp3_force_decrypt: arg.xp3_force_decrypt,
#[cfg(feature = "emote-img")]
emote_pimg_psd_no_diff: arg.emote_pimg_psd_no_diff,
#[cfg(feature = "kirikiri-arc")]
xp3_file_list_path: arg.xp3_file_list_path.clone(),
});
match &arg.command {
args::Command::Export { input, output } => {

View File

@@ -256,7 +256,7 @@ pub struct Schema {
}
impl Schema {
pub fn create_crypt(&self, filename: &str) -> Result<Box<dyn Crypt>> {
pub fn create_crypt(&self, filename: &str, config: &ExtraConfig) -> Result<Box<dyn Crypt>> {
Ok(match &self.crypt {
CryptType::NoCrypt => Box::new(NoCrypt::new()),
CryptType::FateCrypt => Box::new(FateCrypt::new(self.base.clone())),
@@ -354,9 +354,11 @@ impl Schema {
hash_table.clone(),
key_table.bytes.clone(),
)?),
CryptType::RhapsodyCrypt { file_list_name } => {
Box::new(RhapsodyCrypt::new(self.base.clone(), &file_list_name)?)
}
CryptType::RhapsodyCrypt { file_list_name } => Box::new(RhapsodyCrypt::new(
self.base.clone(),
&file_list_name,
config.xp3_file_list_path.as_ref().map(|s| s.as_str()),
)?),
})
}
}
@@ -1543,8 +1545,16 @@ pub struct RhapsodyCrypt {
}
impl RhapsodyCrypt {
pub fn new(base: BaseSchema, file_list_name: &str) -> Result<Self> {
let file_list = query_filename_list(file_list_name)?;
pub fn new(
base: BaseSchema,
file_list_name: &str,
file_list_path: Option<&str>,
) -> Result<Self> {
let file_list = if let Some(path) = file_list_path {
std::fs::read_to_string(path)?
} else {
query_filename_list(file_list_name)?
};
let mut names = HashMap::new();
for name in file_list.lines() {
let name = name.trim();

View File

@@ -10,15 +10,15 @@ use std::sync::{Arc, Mutex};
impl Xp3Archive {
pub fn new<T: Read + Seek + std::fmt::Debug + 'static>(
stream: T,
_config: &ExtraConfig,
config: &ExtraConfig,
filename: &str,
) -> Result<Self> {
let crypt: Box<dyn Crypt> = if let Some(game_title) = &_config.xp3_game_title {
let crypt: Box<dyn Crypt> = if let Some(game_title) = &config.xp3_game_title {
query_crypt_schema(game_title)
.ok_or_else(|| {
anyhow::anyhow!("Unsupported game title for XP3 archive: {}", game_title)
})?
.create_crypt(filename)?
.create_crypt(filename, config)?
} else {
Box::new(NoCrypt::new())
};

View File

@@ -653,6 +653,10 @@ pub struct ExtraConfig {
/// Disable diff handle when exporting Emote PIMG images to PSD files.
/// If enabled, no group layers will be crated if both layer don't have diff_id and group_layer_id attribute.
pub emote_pimg_psd_no_diff: bool,
#[cfg(feature = "kirikiri-arc")]
/// The path to the file list for Kirikiri XP3 archive. This is used to recover file names from hashed values.
/// Only works with some encyrption methods.
pub xp3_file_list_path: Option<String>,
}
#[cfg(feature = "artemis")]