From 5c71e6cb2289ce1bed0c69d6978257cb90767896 Mon Sep 17 00:00:00 2001 From: Zynh0722 Date: Thu, 23 Nov 2023 19:53:57 -0800 Subject: [PATCH] parsing version data also added a binary for testing and an example file for now --- Cargo.toml | 6 +++++ mod-settings.dat | Bin 18573 -> 18574 bytes src/bin/testing.rs | 14 ++++++++++++ src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/bin/testing.rs diff --git a/Cargo.toml b/Cargo.toml index 2a968f1..7c78f83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,12 @@ name = "factorio_types" version = "0.1.0" edition = "2021" +[[bin]] +name = "testing" +path = "src/bin/testing.rs" +doc = false + + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/mod-settings.dat b/mod-settings.dat index 93377579d8ca25aad170f4777f794eb1d762f500..c5e827b6e5dbbbec138ac47ee8f09c7328502769 100644 GIT binary patch delta 11 ScmeC3$k;cLaYL^MBNqS~!UNC% delta 9 QcmeC1$k;oPaYL^M0240*#Q*>R diff --git a/src/bin/testing.rs b/src/bin/testing.rs new file mode 100644 index 0000000..ce3997e --- /dev/null +++ b/src/bin/testing.rs @@ -0,0 +1,14 @@ +use std::{fs::File, io::BufReader}; + +use factorio_types::ModSettings; + +fn main() -> anyhow::Result<()> { + let file = File::open("./mod-settings.dat")?; + let buf_reader = BufReader::new(file); + + let settings = ModSettings::from_reader(buf_reader)?; + + println!("{settings:?}"); + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 39f651d..bfaf133 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,11 @@ -use std::collections::HashMap; +#![feature(array_chunks)] +#![feature(iter_collect_into)] +use std::{collections::HashMap, io::Read}; + +use anyhow::{anyhow, Context}; + +#[derive(Debug)] pub enum PropertyTree { None, Bool(bool), @@ -8,3 +14,49 @@ pub enum PropertyTree { List(Vec), Dictionary(HashMap), } + +#[derive(Debug)] +pub struct ModSettings { + pub version: [u16; 4], + pub data: PropertyTree, +} + +impl ModSettings { + /// This reads from a reader based on this file specification + /// https://wiki.factorio.com/Mod_settings_file_format + pub fn from_reader(mut reader: R) -> anyhow::Result + where + R: Read, + { + // Fetching first 8 little endian bytes representing version + // https://wiki.factorio.com/Version_string_format + let mut version_bytes = [0u8; 8]; + reader + .read_exact(&mut version_bytes) + .context("Failed trying to get first 8 bytes representing version number")?; + + // Grab the null byte that follows the version number + let _padding_byte = reader + .by_ref() + .bytes() + .next() + .ok_or(anyhow!("Unexpected EOF")) + .context("Failed trying to grab null byte that follows version number"); + + // Mapping pairs of 2 u8s into single le u16s + let mut version_map = version_bytes.array_chunks().map(|b| u16::from_le_bytes(*b)); + + // Load u16s into an array + let version = [ + version_map.next().unwrap(), + version_map.next().unwrap(), + version_map.next().unwrap(), + version_map.next().unwrap(), + ]; + + Ok(ModSettings { + version, + data: PropertyTree::None, + }) + } +}