From 0cd80927be786936882291937fccca0f69470e24 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Tue, 29 Aug 2023 07:51:49 +0300 Subject: [PATCH] FString proper encoding --- src/fot/fstring.rs | 16 +++++++--------- src/fot/world.rs | 5 ++++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/fot/fstring.rs b/src/fot/fstring.rs index 28ecd17..be9789a 100644 --- a/src/fot/fstring.rs +++ b/src/fot/fstring.rs @@ -6,7 +6,7 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use encoding_rs::WINDOWS_1251; use std::str; -// FString - Fallout String +// FString - Fallout #[derive(Debug, PartialEq)] pub enum FStringEncoding { @@ -17,6 +17,7 @@ pub enum FStringEncoding { #[derive(Debug)] pub struct FString { encoding: FStringEncoding, + enc_len: usize, str: String } @@ -28,24 +29,24 @@ impl Decoder for FString { let start = offset + 4; if flen & (1<<31) == 0 { // ANSI let str = str::from_utf8(&raw.mem[start..start+len])?; - Ok(FString { encoding: FStringEncoding::ANSI, str: str.to_string() }) + Ok(FString { encoding: FStringEncoding::ANSI, enc_len: len, str: str.to_string() }) } else { // WCS2 let chars: Vec = raw.mem[start..start+len*2] .iter().step_by(2).copied().collect(); let (str, _, _) = WINDOWS_1251.decode(&chars); - Ok(FString { encoding: FStringEncoding::WCS2, str: str.to_string() }) + Ok(FString { encoding: FStringEncoding::WCS2, enc_len: len, str: str.to_string() }) } } fn encode(&self) -> Raw { - let mut buf = vec![0u8, 4]; + let mut buf = vec![0u8; 4]; let mut wdr = Cursor::new(&mut buf[..]); if self.encoding == FStringEncoding::ANSI { let _ = wdr.write_u32::(self.str.len() as u32 ^ (1<<31)); buf.append(&mut self.str.clone().into_bytes()); } else { // WCS2 - let _ = wdr.write_u32::(self.str.len() as u32 | (1<<31)); let (chars, _, _) = WINDOWS_1251.encode(self.str.as_str()); + let _ = wdr.write_u32::(chars.len() as u32 | (1<<31)); for &c in chars.iter() { buf.push(c); buf.push(0); @@ -55,9 +56,6 @@ impl Decoder for FString { } fn get_enc_size(&self) -> usize { - match self.encoding { - FStringEncoding::ANSI => 4 + self.str.len(), - FStringEncoding::WCS2 => 4 + self.str.len() * 2 - } + 4 + self.enc_len } } \ No newline at end of file diff --git a/src/fot/world.rs b/src/fot/world.rs index 1824477..e200800 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -22,9 +22,12 @@ impl World { const WORLD_HDR_LEN: usize = 0x13; pub fn test(&self) -> Result<()> { - let a = FString::decode(&self.data, 0xF6, 0)?; + let a = FString::decode(&self.data, 0xA2, 0)?; dbg!(&a); + let b = a.encode(); + dbg!(&b); + Ok(()) } }