use byteorder::{LE, ReadBytesExt};
use num_enum::TryFromPrimitive;
use std::{fs::File, io::BufReader};
use crate::Result;
use crate::common::errors::ModuleError;
const HEADER_MAGIC: u32 = 0x6468_6F6D;
#[derive(Default, Debug, PartialEq, Eq, TryFromPrimitive, PartialOrd, Ord)]
#[repr(i32)]
pub enum ModuleVersion {
Flight1 = 48,
Release = 51,
CampaignFlight = 52,
#[default]
Season3 = 53,
}
#[derive(Default, Debug)]
pub struct ModuleHeader {
magic: u32,
pub version: ModuleVersion,
pub module_id: i64,
pub file_count: u32,
loadmanifest_index: i32,
runtimeloadmetadata_index: i32,
resourcemetadata_index: i32,
resource_index: i32,
pub(super) strings_size: u32,
pub(super) resource_count: u32,
pub(super) block_count: u32,
build_version: u64,
pub(super) hd1_delta: u64,
pub(super) data_size: u64,
}
impl ModuleHeader {
pub(super) fn read(&mut self, reader: &mut BufReader<File>) -> Result<()> {
self.magic = reader.read_u32::<LE>()?;
if self.magic != HEADER_MAGIC {
return Err(ModuleError::IncorrectMagic(self.magic).into());
}
self.version = ModuleVersion::try_from_primitive(reader.read_i32::<LE>()?)
.map_err(ModuleError::IncorrectVersion)?;
self.module_id = reader.read_i64::<LE>()?;
self.file_count = reader.read_u32::<LE>()?;
self.loadmanifest_index = reader.read_i32::<LE>()?;
self.runtimeloadmetadata_index = reader.read_i32::<LE>()?;
self.resourcemetadata_index = reader.read_i32::<LE>()?;
self.resource_index = reader.read_i32::<LE>()?;
self.strings_size = reader.read_u32::<LE>()?;
self.resource_count = reader.read_u32::<LE>()?;
self.block_count = reader.read_u32::<LE>()?;
self.build_version = reader.read_u64::<LE>()?;
self.hd1_delta = reader.read_u64::<LE>()?;
self.data_size = reader.read_u64::<LE>()?;
if self.version >= ModuleVersion::Release {
reader.seek_relative(8)?; }
Ok(())
}
}