mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-27 06:06:56 +08:00
Use better way to fix
This commit is contained in:
@@ -214,12 +214,6 @@ pub enum BGIStringType {
|
|||||||
Internal,
|
Internal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BGIStringType {
|
|
||||||
pub fn is_internal(&self) -> bool {
|
|
||||||
matches!(self, BGIStringType::Internal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BGIString {
|
pub struct BGIString {
|
||||||
pub offset: usize,
|
pub offset: usize,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::scripts::base::*;
|
|||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::utils::encoding::{decode_to_string, encode_string};
|
use crate::utils::encoding::{decode_to_string, encode_string};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BGIScriptBuilder {}
|
pub struct BGIScriptBuilder {}
|
||||||
@@ -157,16 +157,25 @@ impl Script for BGIScript {
|
|||||||
replacement: Option<&'a ReplacementTable>,
|
replacement: Option<&'a ReplacementTable>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if !self.import_duplicate {
|
if !self.import_duplicate {
|
||||||
let mut str_map = BTreeMap::new();
|
let mut used = HashMap::new();
|
||||||
|
let mut extra = HashMap::new();
|
||||||
let mut mes = messages.iter();
|
let mut mes = messages.iter();
|
||||||
let mut cur_mes = mes.next();
|
let mut cur_mes = mes.next();
|
||||||
for curs in self.strings.iter() {
|
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();
|
||||||
|
}
|
||||||
|
for curs in &self.strings {
|
||||||
if !curs.is_internal() {
|
if !curs.is_internal() {
|
||||||
if cur_mes.is_none() {
|
if cur_mes.is_none() {
|
||||||
cur_mes = mes.next();
|
cur_mes = mes.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if str_map.contains_key(&curs.address) && curs.typ.is_internal() {
|
if used.contains_key(&curs.address) && curs.is_internal() {
|
||||||
|
let (_, new_address) = used.get(&curs.address).unwrap();
|
||||||
|
file.write_u32_at(curs.offset, *new_address as u32)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let nmes = match curs.typ {
|
let nmes = match curs.typ {
|
||||||
@@ -204,33 +213,21 @@ impl Script for BGIScript {
|
|||||||
mes
|
mes
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match str_map.get(&curs.address) {
|
let in_used = match used.get(&curs.address) {
|
||||||
Some(existed) => {
|
Some((s, address)) => {
|
||||||
if existed != &nmes {
|
if s == &nmes {
|
||||||
eprintln!(
|
file.write_u32_at(curs.offset, *address as u32)?;
|
||||||
"Warning: Duplicate string at address {} with different content. Original: {}, New: {}. New string will be ignored. If you want to import it, use --bgi-import-duplicate.",
|
continue;
|
||||||
curs.address, existed, nmes
|
|
||||||
);
|
|
||||||
crate::COUNTER.inc_warning();
|
|
||||||
}
|
}
|
||||||
continue;
|
if let Some(address) = extra.get(&nmes) {
|
||||||
|
file.write_u32_at(curs.offset, *address as u32)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
None => {}
|
None => false,
|
||||||
}
|
};
|
||||||
str_map.insert(curs.address, nmes);
|
let bgi_str_old_offset = curs.address + self.offset;
|
||||||
}
|
|
||||||
if cur_mes.is_some() || mes.next().is_some() {
|
|
||||||
return Err(anyhow::anyhow!("Some messages were not processed."));
|
|
||||||
}
|
|
||||||
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 !self.append && 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])?;
|
file.write_all(&self.data.data[old_offset..bgi_str_old_offset])?;
|
||||||
new_offset += bgi_str_old_offset - old_offset;
|
new_offset += bgi_str_old_offset - old_offset;
|
||||||
@@ -241,13 +238,13 @@ impl Script for BGIScript {
|
|||||||
.cpeek_cstring_at(bgi_str_old_offset)?
|
.cpeek_cstring_at(bgi_str_old_offset)?
|
||||||
.as_bytes_with_nul()
|
.as_bytes_with_nul()
|
||||||
.len();
|
.len();
|
||||||
let nmes = encode_string(encoding, &nmes, false)?;
|
let nmess = encode_string(encoding, &nmes, false)?;
|
||||||
let write_to_original = self.append && nmes.len() + 1 <= old_str_len;
|
let write_to_original = self.append && !in_used && nmess.len() + 1 <= old_str_len;
|
||||||
if write_to_original {
|
if write_to_original {
|
||||||
file.write_all_at(bgi_str_old_offset, &nmes)?;
|
file.write_all_at(bgi_str_old_offset, &nmess)?;
|
||||||
file.write_u8_at(bgi_str_old_offset + nmes.len(), 0)?; // null terminator
|
file.write_u8_at(bgi_str_old_offset + nmess.len(), 0)?; // null terminator
|
||||||
} else {
|
} else {
|
||||||
file.write_all(&nmes)?;
|
file.write_all(&nmess)?;
|
||||||
file.write_u8(0)?; // null terminator
|
file.write_u8(0)?; // null terminator
|
||||||
}
|
}
|
||||||
let new_address = if write_to_original {
|
let new_address = if write_to_original {
|
||||||
@@ -255,22 +252,23 @@ impl Script for BGIScript {
|
|||||||
} else {
|
} else {
|
||||||
new_offset - self.offset
|
new_offset - self.offset
|
||||||
};
|
};
|
||||||
new_address_map.insert(address, new_address);
|
file.write_u32_at(curs.offset, new_address as u32)?;
|
||||||
|
if in_used {
|
||||||
|
extra.insert(nmes, new_address);
|
||||||
|
} else {
|
||||||
|
used.insert(curs.address, (nmes, new_address));
|
||||||
|
}
|
||||||
old_offset += old_str_len;
|
old_offset += old_str_len;
|
||||||
if !write_to_original {
|
if !write_to_original {
|
||||||
new_offset += nmes.len() + 1; // +1 for null terminator
|
new_offset += nmess.len() + 1; // +1 for null terminator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if cur_mes.is_some() || mes.next().is_some() {
|
||||||
|
return Err(anyhow::anyhow!("Some messages were not processed."));
|
||||||
|
}
|
||||||
if !self.append && old_offset < self.data.data.len() {
|
if !self.append && old_offset < self.data.data.len() {
|
||||||
file.write_all(&self.data.data[old_offset..])?;
|
file.write_all(&self.data.data[old_offset..])?;
|
||||||
}
|
}
|
||||||
for bgis in self.strings.iter() {
|
|
||||||
let new_address = new_address_map.get(&bgis.address).ok_or(anyhow::anyhow!(
|
|
||||||
"Address {} not found in new address map.",
|
|
||||||
bgis.address
|
|
||||||
))?;
|
|
||||||
file.write_u32_at(bgis.offset, *new_address as u32)?;
|
|
||||||
}
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mut mes = messages.iter();
|
let mut mes = messages.iter();
|
||||||
|
|||||||
Reference in New Issue
Block a user