From 4068cc5a043dbc0f539507d25e97c4d040f521e1 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 7 Jun 2025 21:07:28 +0800 Subject: [PATCH] Use a more safe way to patch BGI script --- src/args.rs | 11 ++++++++++- src/main.rs | 2 ++ src/scripts/bgi/script.rs | 39 +++++++++++++++++++++++++++++++-------- src/types.rs | 2 ++ 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/args.rs b/src/args.rs index d1f1e06..96019e4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -4,7 +4,11 @@ use clap::{ArgAction, ArgGroup, Parser, Subcommand}; /// Tools for export and import scripts #[derive(Parser, Debug)] #[clap(group = ArgGroup::new("encodingg").multiple(false), group = ArgGroup::new("output_encodingg").multiple(false), group = ArgGroup::new("archive_encodingg").multiple(false))] -#[command(version, about, long_about = None)] +#[command( + version, + about, + long_about = "Tools for export and import scripts\nhttps://github.com/lifegpc/msg-tool" +)] pub struct Arg { #[arg(short = 't', long, value_enum, global = true)] /// Script type @@ -80,6 +84,11 @@ pub struct Arg { /// Duplicate same strings when importing into BGI scripts. /// Enable this will cause BGI scripts to become very large. pub bgi_import_duplicate: bool, + #[cfg(feature = "bgi")] + #[arg(long, action = ArgAction::SetTrue, global = true, alias = "bgi-no-append")] + /// Disable appending new strings to the end of BGI scripts. + /// Disable may cause BGI scripts broken. + pub bgi_disable_append: bool, #[command(subcommand)] /// Command pub command: Command, diff --git a/src/main.rs b/src/main.rs index 27ca2cb..f29a5ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1061,6 +1061,8 @@ fn main() { escude_enum_scr: arg.escude_enum_scr.clone(), #[cfg(feature = "bgi")] bgi_import_duplicate: arg.bgi_import_duplicate, + #[cfg(feature = "bgi")] + bgi_disable_append: arg.bgi_disable_append, }; match &arg.command { args::Command::Export { input, output } => { diff --git a/src/scripts/bgi/script.rs b/src/scripts/bgi/script.rs index 8d34698..085dee0 100644 --- a/src/scripts/bgi/script.rs +++ b/src/scripts/bgi/script.rs @@ -54,6 +54,7 @@ pub struct BGIScript { is_v1: bool, offset: usize, import_duplicate: bool, + append: bool, } impl std::fmt::Debug for BGIScript { @@ -79,6 +80,7 @@ impl BGIScript { is_v1: true, offset, import_duplicate: config.bgi_import_duplicate, + append: !config.bgi_disable_append, }) } else { let mut parser = V0Parser::new(data.to_ref()); @@ -91,6 +93,7 @@ impl BGIScript { is_v1: false, offset: 0, import_duplicate: config.bgi_import_duplicate, + append: !config.bgi_disable_append, }) } } @@ -203,9 +206,13 @@ impl Script for BGIScript { let mut old_offset = 0; let mut new_offset = 0; let mut new_address_map = BTreeMap::new(); + if self.append { + file.write_all(&self.data.data)?; + new_offset = self.data.data.len(); + } for (address, nmes) in str_map { let bgi_str_old_offset = address + self.offset; - if old_offset < bgi_str_old_offset { + if !self.append && old_offset < bgi_str_old_offset { file.write_all(&self.data.data[old_offset..bgi_str_old_offset])?; new_offset += bgi_str_old_offset - old_offset; old_offset = bgi_str_old_offset; @@ -216,14 +223,26 @@ impl Script for BGIScript { .as_bytes_with_nul() .len(); let nmes = encode_string(encoding, &nmes, false)?; - file.write_all(&nmes)?; - file.write_u8(0)?; // null terminator - let new_address = new_offset - self.offset; + let write_to_original = self.append && nmes.len() + 1 <= old_str_len; + if write_to_original { + file.write_all_at(bgi_str_old_offset, &nmes)?; + file.write_u8_at(bgi_str_old_offset + nmes.len(), 0)?; // null terminator + } else { + file.write_all(&nmes)?; + file.write_u8(0)?; // null terminator + } + let new_address = if write_to_original { + bgi_str_old_offset - self.offset + } else { + new_offset - self.offset + }; new_address_map.insert(address, new_address); old_offset += old_str_len; - new_offset += nmes.len() + 1; // +1 for null terminator + if !write_to_original { + new_offset += nmes.len() + 1; // +1 for null terminator + } } - if old_offset < self.data.data.len() { + if !self.append && old_offset < self.data.data.len() { file.write_all(&self.data.data[old_offset..])?; } for bgis in self.strings.iter() { @@ -242,6 +261,10 @@ impl Script for BGIScript { let mut cur_str = strs.next(); let mut old_offset = 0; let mut new_offset = 0; + if self.append { + file.write_all(&self.data.data)?; + new_offset = self.data.data.len(); + } while let Some(curs) = cur_str { if !curs.is_internal() { if cur_mes.is_none() { @@ -249,7 +272,7 @@ impl Script for BGIScript { } } let bgi_str_old_offset = curs.address + self.offset; - if old_offset < bgi_str_old_offset { + if !self.append && old_offset < bgi_str_old_offset { file.write_all(&self.data.data[old_offset..bgi_str_old_offset])?; new_offset += bgi_str_old_offset - old_offset; old_offset = bgi_str_old_offset; @@ -314,7 +337,7 @@ impl Script for BGIScript { for str in nstrs { file.write_u32_at(str.offset, str.address as u32)?; } - if old_offset < self.data.data.len() { + if !self.append && old_offset < self.data.data.len() { file.write_all(&self.data.data[old_offset..])?; } Ok(()) diff --git a/src/types.rs b/src/types.rs index 5877e17..17c22a2 100644 --- a/src/types.rs +++ b/src/types.rs @@ -195,6 +195,8 @@ pub struct ExtraConfig { pub escude_enum_scr: Option, #[cfg(feature = "bgi")] pub bgi_import_duplicate: bool, + #[cfg(feature = "bgi")] + pub bgi_disable_append: bool, } #[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]