From 09d850256fc92d666f9cabcb0e079e32ef0b4740 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Tue, 3 Jun 2025 19:40:04 +0800 Subject: [PATCH] Add import support for escude script --- src/ext/io.rs | 6 ++++++ src/main.rs | 2 +- src/scripts/base.rs | 15 ++++++++++++- src/scripts/bgi/script.rs | 2 +- src/scripts/circus/script.rs | 5 ++--- src/scripts/escude/list.rs | 4 ++-- src/scripts/escude/script.rs | 42 ++++++++++++++++++++++++++---------- 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/ext/io.rs b/src/ext/io.rs index da11865..d27247e 100644 --- a/src/ext/io.rs +++ b/src/ext/io.rs @@ -458,6 +458,8 @@ pub trait WriteExt { fn write_i64_be(&mut self, value: i64) -> Result<()>; fn write_i128(&mut self, value: i128) -> Result<()>; fn write_i128_be(&mut self, value: i128) -> Result<()>; + + fn write_cstring(&mut self, value: &CString) -> Result<()>; } impl WriteExt for T { @@ -515,6 +517,10 @@ impl WriteExt for T { fn write_i128_be(&mut self, value: i128) -> Result<()> { self.write_all(&value.to_be_bytes()) } + + fn write_cstring(&mut self, value: &CString) -> Result<()> { + self.write_all(value.as_bytes_with_nul()) + } } pub struct MemReader { diff --git a/src/main.rs b/src/main.rs index 7265039..858446f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -627,7 +627,7 @@ pub fn import_script( } format::fmt_message(&mut mes, fmt, *builder.script_type()); - script.import_messages(mes, &patched_f, encoding, repl)?; + script.import_messages_filename(mes, &patched_f, encoding, repl)?; Ok(types::ScriptResult::Ok) } diff --git a/src/scripts/base.rs b/src/scripts/base.rs index 88f326f..77cb02d 100644 --- a/src/scripts/base.rs +++ b/src/scripts/base.rs @@ -100,7 +100,7 @@ pub trait Script: std::fmt::Debug { fn import_messages( &self, _messages: Vec, - _filename: &str, + _file: Box, _encoding: Encoding, _replacement: Option<&ReplacementTable>, ) -> Result<()> { @@ -112,6 +112,18 @@ pub trait Script: std::fmt::Debug { Ok(()) } + fn import_messages_filename( + &self, + _messages: Vec, + _filename: &str, + _encoding: Encoding, + _replacement: Option<&ReplacementTable>, + ) -> Result<()> { + let f = std::fs::File::create(_filename)?; + let f = std::io::BufWriter::new(f); + self.import_messages(_messages, Box::new(f), _encoding, _replacement) + } + fn custom_export(&self, _filename: &std::path::Path, _encoding: Encoding) -> Result<()> { Err(anyhow::anyhow!( "This script type does not support custom export." @@ -138,6 +150,7 @@ pub trait Script: std::fmt::Debug { output_encoding: Encoding, ) -> Result<()> { let f = std::fs::File::create(filename)?; + let f = std::io::BufWriter::new(f); self.custom_import(custom_filename, Box::new(f), encoding, output_encoding) } diff --git a/src/scripts/bgi/script.rs b/src/scripts/bgi/script.rs index 542ff43..4447786 100644 --- a/src/scripts/bgi/script.rs +++ b/src/scripts/bgi/script.rs @@ -144,7 +144,7 @@ impl Script for BGIScript { fn import_messages( &self, _messages: Vec, - _filename: &str, + _filename: Box, _encoding: Encoding, _replacement: Option<&ReplacementTable>, ) -> Result<()> { diff --git a/src/scripts/circus/script.rs b/src/scripts/circus/script.rs index dbf9cd7..7feb104 100644 --- a/src/scripts/circus/script.rs +++ b/src/scripts/circus/script.rs @@ -224,7 +224,7 @@ impl Script for CircusMesScript { fn import_messages( &self, messages: Vec, - filename: &str, + mut writer: Box, encoding: Encoding, replacement: Option<&ReplacementTable>, ) -> Result<()> { @@ -365,8 +365,7 @@ impl Script for CircusMesScript { ); 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)?; + writer.write_all(&buffer)?; Ok(()) } } diff --git a/src/scripts/escude/list.rs b/src/scripts/escude/list.rs index 6681c11..656a18f 100644 --- a/src/scripts/escude/list.rs +++ b/src/scripts/escude/list.rs @@ -1,8 +1,8 @@ +use crate::ext::io::*; use crate::scripts::base::*; use crate::types::*; -use crate::utils::encoding::encode_string; +use crate::utils::encoding::{decode_to_string, encode_string}; use crate::utils::struct_pack::*; -use crate::{ext::io::*, utils::encoding::decode_to_string}; use anyhow::Result; use msg_tool_macro::*; use serde::{Deserialize, Serialize}; diff --git a/src/scripts/escude/script.rs b/src/scripts/escude/script.rs index ae8cbb1..41e52d9 100644 --- a/src/scripts/escude/script.rs +++ b/src/scripts/escude/script.rs @@ -2,8 +2,10 @@ use crate::ext::io::*; use crate::scripts::base::*; use crate::types::*; use crate::utils::encoding::{decode_to_string, encode_string}; +use crate::utils::struct_pack::StructPack; use anyhow::Result; use std::collections::HashMap; +use std::ffi::CString; use std::io::Read; use unicode_segmentation::UnicodeSegmentation; @@ -50,7 +52,6 @@ impl ScriptBuilder for EscudeBinScriptBuilder { #[derive(Debug)] pub struct EscudeBinScript { - offsets: Vec, vms: Vec, unk1: u32, strings: Vec, @@ -91,12 +92,7 @@ impl EscudeBinScript { strings.push(decode_to_string(encoding, s.as_bytes())?); } } - Ok(EscudeBinScript { - offsets, - vms, - unk1, - strings, - }) + Ok(EscudeBinScript { vms, unk1, strings }) } } @@ -122,11 +118,35 @@ impl Script for EscudeBinScript { fn import_messages( &self, - _messages: Vec, - _filename: &str, - _encoding: Encoding, - _replacement: Option<&ReplacementTable>, + messages: Vec, + mut writer: Box, + encoding: Encoding, + replacement: Option<&ReplacementTable>, ) -> Result<()> { + writer.write_all(b"ESCR1_00")?; + let mut offsets = Vec::with_capacity(messages.len()); + let mut strs = Vec::with_capacity(messages.len()); + let mut len = 0; + for message in messages { + offsets.push(len); + let mut s = message.message; + if let Some(repl) = replacement { + for (from, to) in &repl.map { + s = s.replace(from, to); + } + } + let encoded = encode_string(encoding, &s, true)?; + len += encoded.len() as u32 + 1; + strs.push(CString::new(encoded)?); + } + writer.write_u32(offsets.len() as u32)?; + offsets.pack(&mut writer, false, encoding)?; + writer.write_u32(self.vms.len() as u32)?; + writer.write_all(&self.vms)?; + writer.write_u32(self.unk1)?; + for s in strs { + writer.write_all(s.as_bytes_with_nul())?; + } Ok(()) }