diff --git a/src/args.rs b/src/args.rs index f4bebcc..0bbc356 100644 --- a/src/args.rs +++ b/src/args.rs @@ -80,6 +80,9 @@ pub struct ImportArgs { #[arg(long)] /// Name table file pub name_csv: Option, + #[arg(long)] + /// Replacement table file + pub replacement_json: Option, } #[derive(Subcommand, Debug)] diff --git a/src/main.rs b/src/main.rs index c2ddd7e..fcc0a76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,6 +183,7 @@ pub fn import_script( imp_cfg: &args::ImportArgs, is_dir: bool, name_csv: Option<&std::collections::HashMap>, + repl: Option<&types::ReplacementTable>, ) -> anyhow::Result { eprintln!("Importing {}", filename); let (script, builder) = parse_script(filename, arg, config)?; @@ -253,7 +254,8 @@ pub fn import_script( None => {} } format::fmt_message(&mut mes, fmt, *builder.script_type()); - script.import_messages(mes, &patched_f, encoding)?; + + script.import_messages(mes, &patched_f, encoding, repl)?; Ok(types::ScriptResult::Ok) } @@ -312,6 +314,15 @@ fn main() { } None => None, }; + let repl = match &args.replacement_json { + Some(replacement_json) => { + let b = utils::files::read_file(replacement_json).unwrap(); + let s = String::from_utf8(b).unwrap(); + let table = serde_json::from_str::(&s).unwrap(); + Some(table) + } + None => None, + }; let (scripts, is_dir) = utils::files::collect_files(&args.input, arg.recursive).unwrap(); if is_dir { @@ -326,7 +337,15 @@ fn main() { } } for script in scripts.iter() { - let re = import_script(&script, &arg, &cfg, args, is_dir, name_csv.as_ref()); + let re = import_script( + &script, + &arg, + &cfg, + args, + is_dir, + name_csv.as_ref(), + repl.as_ref(), + ); match re { Ok(s) => { COUNTER.inc(s); diff --git a/src/scripts/base.rs b/src/scripts/base.rs index 068d558..0ae2696 100644 --- a/src/scripts/base.rs +++ b/src/scripts/base.rs @@ -32,5 +32,6 @@ pub trait Script: std::fmt::Debug { messages: Vec, filename: &str, encoding: Encoding, + replacement: Option<&ReplacementTable>, ) -> Result<()>; } diff --git a/src/scripts/bgi/script.rs b/src/scripts/bgi/script.rs index 42e66f4..954982b 100644 --- a/src/scripts/bgi/script.rs +++ b/src/scripts/bgi/script.rs @@ -141,6 +141,7 @@ impl Script for BGIScript { _messages: Vec, _filename: &str, _encoding: Encoding, + _replacement: Option<&ReplacementTable>, ) -> Result<()> { Ok(()) } diff --git a/src/scripts/circus/script.rs b/src/scripts/circus/script.rs index 1e10537..e929d60 100644 --- a/src/scripts/circus/script.rs +++ b/src/scripts/circus/script.rs @@ -228,17 +228,18 @@ impl Script for CircusMesScript { messages: Vec, filename: &str, encoding: Encoding, + replacement: Option<&ReplacementTable>, ) -> Result<()> { let mut repls = Vec::new(); if !encoding.is_jis() { fn insert_repl( - repls: &mut Vec<(&'static str, String)>, + repls: &mut Vec<(String, String)>, s: &'static str, encoding: Encoding, ) -> Result<()> { let jis = encode_string(Encoding::Cp932, s, true)?; let out = decode_to_string(encoding, &jis)?; - repls.push((s, out)); + repls.push((s.to_string(), out)); Ok(()) } let _ = insert_repl(&mut repls, "{", encoding); @@ -251,6 +252,14 @@ impl Script for CircusMesScript { crate::COUNTER.inc_warning(); } } + match replacement { + Some(repl) => { + for (k, v) in repl.map.iter() { + repls.push((k.to_string(), v.to_string())); + } + } + None => {} + } let mut buffer = Vec::with_capacity(self.data.len()); buffer.extend_from_slice(&self.data[..self.asm_bin_offset]); let mut nmes = Vec::with_capacity(messages.len()); @@ -290,7 +299,7 @@ impl Script for CircusMesScript { t }; for i in repls.iter() { - s = s.replace(i.0, i.1.as_str()); + s = s.replace(i.0.as_str(), i.1.as_str()); } let mut text = encode_string(encoding, &s, false)?; buffer.push(token.value); @@ -323,7 +332,7 @@ impl Script for CircusMesScript { t }; for i in repls.iter() { - s = s.replace(i.0, i.1.as_str()); + s = s.replace(i.0.as_str(), i.1.as_str()); } buffer.push(token.value); let text = encode_string(encoding, &s, false)?; diff --git a/src/types.rs b/src/types.rs index 8307751..62bc732 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,6 @@ use clap::ValueEnum; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; #[derive(Copy, Clone, Serialize, Deserialize, Debug)] #[serde(untagged, rename_all = "camelCase")] @@ -235,3 +236,9 @@ pub struct NameTableCell { #[serde(rename = "Count")] pub count: usize, } + +#[derive(Debug, Serialize, Deserialize)] +pub struct ReplacementTable { + #[serde(flatten)] + pub map: HashMap, +}