diff --git a/src/main.rs b/src/main.rs index ec2651a..a2fb193 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ pub mod args; +pub mod output_scripts; pub mod scripts; pub mod types; pub mod utils; @@ -82,7 +83,10 @@ pub fn parse_script( filename: &str, arg: &args::Arg, config: &types::ExtraConfig, -) -> anyhow::Result<(Box, &'static Box)> { +) -> anyhow::Result<( + Box, + &'static Box, +)> { match &arg.script_type { Some(typ) => { for builder in scripts::BUILDER.iter() { @@ -160,7 +164,13 @@ pub fn export_script( let mut f = utils::files::write_file(&f)?; f.write_all(&b)?; } - _ => {} + types::OutputScriptType::M3t => { + let enc = get_output_encoding(arg); + let s = output_scripts::m3t::M3tDumper::dump(&mes); + let b = utils::encoding::encode_string(enc, &s)?; + let mut f = utils::files::write_file(&f)?; + f.write_all(&b)?; + } } Ok(()) } @@ -189,6 +199,10 @@ pub fn import_script( } else { imp_cfg.output.clone() }; + if !std::fs::exists(&out_f).unwrap_or(false) { + eprintln!("Output file does not exist"); + return Ok(()); + } let mes = match of { types::OutputScriptType::Json => { let enc = get_output_encoding(arg); @@ -196,8 +210,12 @@ pub fn import_script( let s = utils::encoding::decode_to_string(enc, &b)?; serde_json::from_str::>(&s)? } - _ => { - return Err(anyhow::anyhow!("Unsupported script type")); + types::OutputScriptType::M3t => { + let enc = get_output_encoding(arg); + let b = utils::files::read_file(&out_f)?; + let s = utils::encoding::decode_to_string(enc, &b)?; + let mut parser = output_scripts::m3t::M3tParser::new(&s); + parser.parse()? } }; if mes.is_empty() { @@ -244,8 +262,7 @@ fn main() { std::fs::create_dir_all(op).unwrap(); } } - None => { - } + None => {} } } for script in scripts.iter() { diff --git a/src/output_scripts/m3t.rs b/src/output_scripts/m3t.rs new file mode 100644 index 0000000..748913e --- /dev/null +++ b/src/output_scripts/m3t.rs @@ -0,0 +1,79 @@ +use crate::types::Message; +use anyhow::Result; + +pub struct M3tParser<'a> { + str: &'a str, + line: usize, +} + +impl<'a> M3tParser<'a> { + pub fn new(str: &'a str) -> Self { + M3tParser { str, line: 1 } + } + + fn next_line(&mut self) -> Option<&'a str> { + match self.str.find('\n') { + Some(pos) => { + let line = &self.str[..pos]; + self.str = &self.str[pos + 1..]; + self.line += 1; + Some(line.trim()) + } + None => { + if !self.str.is_empty() { + let line = self.str; + self.str = ""; + Some(line) + } else { + None + } + } + } + } + + pub fn parse(&mut self) -> Result> { + let mut messages = Vec::new(); + let mut name = None; + while let Some(line) = self.next_line() { + if line.is_empty() { + continue; + } + if line.starts_with("○") { + let line = line[3..].trim(); + if line.starts_with("NAME:") { + name = Some(line[5..].trim().to_string()); + } + } else if line.starts_with("●") { + let message = line[3..].trim(); + messages.push(Message::new(message.replace("\\n", "\n"), name.take())); + } else { + return Err(anyhow::anyhow!( + "Invalid line format at line {}: {}", + self.line, + line + )); + } + } + Ok(messages) + } +} + +pub struct M3tDumper {} + +impl M3tDumper { + pub fn dump(messages: &[Message]) -> String { + let mut result = String::new(); + for message in messages { + if let Some(name) = &message.name { + result.push_str(&format!("○ NAME: {}\n\n", name)); + } + result.push_str(&format!("○ {}\n", message.message.replace("\n", "\\n"))); + if message.message.starts_with("「") { + result.push_str("● 「」\n\n"); + } else { + result.push_str("●\n\n"); + } + } + result + } +} diff --git a/src/output_scripts/mod.rs b/src/output_scripts/mod.rs new file mode 100644 index 0000000..52fe378 --- /dev/null +++ b/src/output_scripts/mod.rs @@ -0,0 +1 @@ +pub mod m3t; diff --git a/src/scripts/circus/script.rs b/src/scripts/circus/script.rs index 64f4619..8d7c0f7 100644 --- a/src/scripts/circus/script.rs +++ b/src/scripts/circus/script.rs @@ -311,10 +311,7 @@ impl Script for CircusMesScript { self.asm_bin_offset + token.offset + token.length, self.data.len(), ); - buffer.extend_from_slice( - &self.data[self.asm_bin_offset + token.offset - ..len] - ); + buffer.extend_from_slice(&self.data[self.asm_bin_offset + token.offset..len]); } let mut f = crate::utils::files::write_file(filename)?; f.write_all(&buffer)?; diff --git a/src/types.rs b/src/types.rs index 7c1d285..40e2fda 100644 --- a/src/types.rs +++ b/src/types.rs @@ -43,7 +43,7 @@ pub enum TextEncoding { /// Script type pub enum OutputScriptType { /// Text script - Txt, + M3t, /// JSON which can be used for GalTransl Json, } @@ -51,7 +51,7 @@ pub enum OutputScriptType { impl AsRef for OutputScriptType { fn as_ref(&self) -> &str { match self { - OutputScriptType::Txt => "txt", + OutputScriptType::M3t => "m3t", OutputScriptType::Json => "json", } }