From 584d3610951f7de3ee21416b3bcc64fd3847fe27 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Tue, 29 Aug 2023 23:01:44 +0300 Subject: [PATCH] cargo fmt --- src/fot/decoder.rs | 14 +++++++---- src/fot/fstring.rs | 52 +++++++++++++++++++++++++++-------------- src/fot/raw.rs | 50 ++++++++++++++++++++++++--------------- src/fot/save.rs | 34 +++++++++++++-------------- src/fot/tag.rs | 21 +++++++++-------- src/fot/world.rs | 58 ++++++++++++++++++++++++++++++---------------- src/main.rs | 5 ++-- 7 files changed, 142 insertions(+), 92 deletions(-) diff --git a/src/fot/decoder.rs b/src/fot/decoder.rs index 41990e5..6e31e59 100644 --- a/src/fot/decoder.rs +++ b/src/fot/decoder.rs @@ -1,6 +1,6 @@ -use std::str; -use anyhow::Result; use super::raw::Raw; +use anyhow::Result; +use std::str; pub trait Decoder: Sized { fn decode(raw: &Raw, offset: usize, size: usize) -> Result; @@ -13,17 +13,21 @@ impl Decoder for String { let str = &raw.mem[offset..]; match str.iter().position(|&c| c == 0) { Some(pos) => Ok(str::from_utf8(&str[..pos])?.to_string()), - None => Ok(str::from_utf8(&raw.mem[offset..offset+size])?.to_string()) + None => Ok(str::from_utf8(&raw.mem[offset..offset + size])?.to_string()), } } fn encode(&self) -> Result { let mut str = self.as_bytes().to_vec(); str.push(0); - Ok(Raw { offset: 0, size: str.len(), mem: str}) + Ok(Raw { + offset: 0, + size: str.len(), + mem: str, + }) } fn get_enc_size(&self) -> usize { self.len() + 1 } -} \ No newline at end of file +} diff --git a/src/fot/fstring.rs b/src/fot/fstring.rs index 930a84d..4549709 100644 --- a/src/fot/fstring.rs +++ b/src/fot/fstring.rs @@ -1,39 +1,52 @@ use super::decoder::Decoder; use super::raw::Raw; use anyhow::Result; -use std::io::Cursor; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use encoding_rs::WINDOWS_1251; +use std::io::Cursor; // FString - Fallout #[derive(Debug, PartialEq)] pub enum FStringEncoding { ANSI, - WCS2 + WCS2, } #[derive(Debug)] pub struct FString { pub encoding: FStringEncoding, pub enc_len: usize, - pub str: String + pub str: String, } impl Decoder for FString { fn decode(raw: &Raw, offset: usize, _: usize) -> Result { let mut rdr = Cursor::new(&raw.mem[offset..]); let flen = rdr.read_u32::()? as usize; - let len = flen & !(1<<31); + let len = flen & !(1 << 31); let start = offset + 4; - if flen & (1<<31) == 0 { // ANSI - let (str, _, _) = WINDOWS_1251.decode(&raw.mem[start..start+len]); - 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(); + if flen & (1 << 31) == 0 { + // ANSI + let (str, _, _) = WINDOWS_1251.decode(&raw.mem[start..start + len]); + 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, enc_len: len, str: str.to_string() }) + Ok(FString { + encoding: FStringEncoding::WCS2, + enc_len: len, + str: str.to_string(), + }) } } @@ -42,22 +55,27 @@ impl Decoder for FString { let mut wdr = Cursor::new(&mut buf[..]); let (chars, _, _) = WINDOWS_1251.encode(self.str.as_str()); if self.encoding == FStringEncoding::ANSI { - wdr.write_u32::(chars.len() as u32 & !(1<<31))?; + wdr.write_u32::(chars.len() as u32 & !(1 << 31))?; buf.extend(chars.iter()); - } else { // WCS2 - wdr.write_u32::(chars.len() as u32 | (1<<31))?; + } else { + // WCS2 + wdr.write_u32::(chars.len() as u32 | (1 << 31))?; for &c in chars.iter() { buf.push(c); buf.push(0); } }; - Ok(Raw { offset: 0, size: buf.len(), mem: buf }) + Ok(Raw { + offset: 0, + size: buf.len(), + mem: buf, + }) } fn get_enc_size(&self) -> usize { 4 + match self.encoding { FStringEncoding::ANSI => self.enc_len, - FStringEncoding::WCS2 => self.enc_len * 2 + FStringEncoding::WCS2 => self.enc_len * 2, } } -} \ No newline at end of file +} diff --git a/src/fot/raw.rs b/src/fot/raw.rs index ecf2761..a7a20f6 100644 --- a/src/fot/raw.rs +++ b/src/fot/raw.rs @@ -1,27 +1,31 @@ -use std::io::BufWriter; -use std::io::Write; -use std::str; +use anyhow::Result; +use memmem::{Searcher, TwoWaySearcher}; use std::fs; use std::fs::OpenOptions; +use std::io::BufWriter; +use std::io::Write; use std::path::Path; -use memmem::{Searcher, TwoWaySearcher}; -use anyhow::Result; +use std::str; #[derive(Debug)] pub struct Raw { pub offset: usize, pub size: usize, - pub mem: Vec + pub mem: Vec, } impl Raw { - pub fn join(offset: usize, size: usize, raws: &mut [Raw], ) -> Raw { + pub fn join(offset: usize, size: usize, raws: &mut [Raw]) -> Raw { let mut mem: Vec = Vec::new(); for raw in raws.iter_mut() { mem.append(&mut raw.mem); } - Raw { offset: offset, size: size, mem: mem } + Raw { + offset: offset, + size: size, + mem: mem, + } } pub fn find_str(&self, str: &str, offset: usize) -> Option { @@ -30,10 +34,10 @@ impl Raw { } pub fn find_str_backwards(&self, str: &str) -> Option { - for i in (0..self.mem.len()-str.len()).step_by(1024).rev() { + for i in (0..self.mem.len() - str.len()).step_by(1024).rev() { match self.find_str(str, i) { - Some(offset) => return Some(i+offset), - None => continue + Some(offset) => return Some(i + offset), + None => continue, }; } @@ -42,15 +46,23 @@ impl Raw { pub fn load_file(path: &Path) -> Result { let mem = fs::read(path)?; - - Ok(Self { offset: 0, size: mem.len(), mem }) + + Ok(Self { + offset: 0, + size: mem.len(), + mem, + }) } pub fn assemble_file(&self, path: &Path, blocks: Vec) -> Result<()> { - let mut file = BufWriter::new(OpenOptions::new() - .create(true).truncate(true).write(true).open(path)?); - - + let mut file = BufWriter::new( + OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(path)?, + ); + let mut sorted = blocks; sorted.sort_by(|a, b| a.offset.cmp(&b.offset)); @@ -63,7 +75,7 @@ impl Raw { file.write(&block.mem)?; // padding if block.size > block.mem.len() { - for _ in 0..block.size - block.mem.len() { + for _ in 0..block.size - block.mem.len() { file.write(&[0])?; } } @@ -76,4 +88,4 @@ impl Raw { file.flush()?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/fot/save.rs b/src/fot/save.rs index 154288d..192adbf 100644 --- a/src/fot/save.rs +++ b/src/fot/save.rs @@ -1,16 +1,16 @@ -use std::str; -use std::path::Path; +use super::decoder::Decoder; +use super::raw::Raw; +use super::world::World; use anyhow::anyhow; use anyhow::Result; use byteorder::{ByteOrder, LittleEndian}; -use super::raw::Raw; -use super::world::World; -use super::decoder::Decoder; +use std::path::Path; +use std::str; #[derive(Debug)] pub struct Save { pub raw: Raw, - pub world: World + pub world: World, } impl Save { @@ -21,21 +21,21 @@ impl Save { let raw = Raw::load_file(path)?; let world_offset = match raw.find_str_backwards(Self::WORLD_TAG) { Some(offset) => offset, - None => return Err(anyhow!("no world found in file")) + None => return Err(anyhow!("no world found in file")), }; - + let mut world_size: usize = 0; { let campaign = match raw.find_str(Self::CAMPAIGN_TAG, world_offset) { Some(campaign) => world_offset + campaign, - None => return Err(anyhow!("no campaign found after world")) + None => return Err(anyhow!("no campaign found after world")), }; - for i in (campaign-256..campaign).rev() { - let fsize = LittleEndian::read_u32(&raw.mem[i..i+4]); - if fsize & (1<<31) != 0 { - let size = fsize ^ (1<<31); - if size as usize <= campaign-i { + for i in (campaign - 256..campaign).rev() { + let fsize = LittleEndian::read_u32(&raw.mem[i..i + 4]); + if fsize & (1 << 31) != 0 { + let size = fsize ^ (1 << 31); + if size as usize <= campaign - i { world_size = i - world_offset; break; } @@ -51,10 +51,8 @@ impl Save { } pub fn save(&self, path: &Path) -> Result<()> { - self.raw.assemble_file(path, vec![ - self.world.encode()? - ])?; + self.raw.assemble_file(path, vec![self.world.encode()?])?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/fot/tag.rs b/src/fot/tag.rs index 955651e..7c787ef 100644 --- a/src/fot/tag.rs +++ b/src/fot/tag.rs @@ -1,28 +1,29 @@ -use anyhow::Result; -use super::raw::Raw; use super::decoder::Decoder; +use super::raw::Raw; +use anyhow::Result; #[derive(Debug)] pub struct Tag { pub name: String, - pub version: String + pub version: String, } impl Decoder for Tag { fn decode(raw: &Raw, offset: usize, size: usize) -> Result { let name = String::decode(raw, offset, size)?; - let version = String::decode(raw, offset + name.len()+1, 0)?; - Ok(Tag {name, version}) + let version = String::decode(raw, offset + name.len() + 1, 0)?; + Ok(Tag { name, version }) } fn encode(&self) -> Result { - Ok(Raw::join(0, self.get_enc_size(), &mut [ - self.name.encode()?, - self.version.encode()? - ])) + Ok(Raw::join( + 0, + self.get_enc_size(), + &mut [self.name.encode()?, self.version.encode()?], + )) } fn get_enc_size(&self) -> usize { self.name.get_enc_size() + self.version.get_enc_size() } -} \ No newline at end of file +} diff --git a/src/fot/world.rs b/src/fot/world.rs index c363173..5fba7b0 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -1,22 +1,20 @@ -use crate::fot::fstring::FStringEncoding; - use super::decoder::Decoder; +use super::fstring::FString; use super::raw::Raw; use super::tag::Tag; -use super::fstring::FString; use anyhow::anyhow; use anyhow::Result; -use std::io::Cursor; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use inflate::inflate_bytes_zlib; use deflate::deflate_bytes_zlib; +use inflate::inflate_bytes_zlib; +use std::io::Cursor; #[derive(Debug)] pub struct World { pub tag: Tag, pub uncompressed_size: u32, - pub data: Raw + pub data: Raw, } impl World { @@ -28,11 +26,11 @@ impl World { let mut cur = sgd_start; cur += Tag::decode(&self.data, sgd_start, 0)?.get_enc_size(); cur += 0x48; - + let mut rdr = Cursor::new(&self.data.mem[..]); rdr.set_position(cur as u64); let N = rdr.read_u32::()?; - + let mut names: Vec = Vec::new(); cur += 4; for _ in 0..N { @@ -40,7 +38,7 @@ impl World { cur += name.get_enc_size(); names.push(name); } - //dbg!(names); + dbg!(names); let unk1 = rdr.read_u32::()?; cur += 4; @@ -65,14 +63,22 @@ impl World { impl Decoder for World { fn decode(raw: &Raw, offset: usize, size: usize) -> Result { let tag = Tag::decode(raw, offset, Self::WORLD_TAG_LEN)?; - - let mut rdr = Cursor::new(&raw.mem[offset+Self::WORLD_TAG_LEN..]); + + let mut rdr = Cursor::new(&raw.mem[offset + Self::WORLD_TAG_LEN..]); let uncompressed_size = rdr.read_u32::()?; let data_start = offset + Self::WORLD_HDR_LEN; - let data = inflate_bytes_zlib(&raw.mem[data_start..data_start+size]) - .map_err(|e| anyhow!(e))?; - Ok(World { tag, uncompressed_size, data: Raw { offset, size, mem: data } }) + let data = + inflate_bytes_zlib(&raw.mem[data_start..data_start + size]).map_err(|e| anyhow!(e))?; + Ok(World { + tag, + uncompressed_size, + data: Raw { + offset, + size, + mem: data, + }, + }) } fn encode(&self) -> Result { @@ -84,14 +90,26 @@ impl Decoder for World { } let data = deflate_bytes_zlib(&self.data.mem); - Ok(Raw::join(self.data.offset, self.data.size, &mut [ - self.tag.encode()?, - Raw { offset: Self::WORLD_TAG_LEN, size: 8, mem: hdr.to_vec()}, - Raw { offset: Self::WORLD_HDR_LEN, size: data.len(), mem: data} - ])) + Ok(Raw::join( + self.data.offset, + self.data.size, + &mut [ + self.tag.encode()?, + Raw { + offset: Self::WORLD_TAG_LEN, + size: 8, + mem: hdr.to_vec(), + }, + Raw { + offset: Self::WORLD_HDR_LEN, + size: data.len(), + mem: data, + }, + ], + )) } fn get_enc_size(&self) -> usize { Self::WORLD_HDR_LEN + self.data.mem.len() } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 7572c50..adbb602 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,9 +11,8 @@ fn main() { Some(path) => path, None => "out.bin" };*/ - - + let save = Save::load(Path::new(save_path)).expect("load save"); save.world.test().expect("test"); //save.save(Path::new("out.sav")).expect("failed to save"); -} \ No newline at end of file +}