ra2_mix/xcc_package/
mod.rs1use crate::{Ra2Error, CncGame, checksum::ra2_crc, constants::*, crypto::{decrypt_blowfish_key, decrypt_mix_header, get_decryption_block_sizing}, MixDatabase};
2use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
3use std::{
4 collections::HashMap,
5 fs::File,
6 io::{Seek, SeekFrom, Write},
7 path::Path,
8};
9
10pub mod reader;
11pub mod writer;
12
13#[derive(Default, Debug)]
15pub struct MixPackage {
16 pub game: CncGame,
18 pub files: HashMap<String, Vec<u8>>,
20}
21
22
23
24#[derive(Copy, Debug, Clone)]
26struct MixHeader {
27 pub flags: Option<u32>,
29 pub file_count: u16,
31 pub data_size: u32,
33}
34
35#[derive(Debug, Clone, Copy)]
37struct FileEntry {
38 pub id: u32,
40 pub offset: i32,
42 pub size: i32,
44}
45#[derive(Debug, Clone)]
47struct FileInfo {
48 file_id: u32,
50 data: Vec<u8>,
52}
53
54impl MixPackage {
55 pub fn add_any(&mut self, name: String, data: Vec<u8>) {
69 self.files.insert(name, data);
70 }
71
72 pub fn add_file(&mut self, data: &Path) -> Result<usize, Ra2Error> {
89 if !data.is_file() {
90 return Err(Ra2Error::FileNotFound("must file".to_string()));
91 }
92 let name = data.file_name().and_then(|s| s.to_str()).ok_or(Ra2Error::FileNotFound("".to_string()))?;
93 let data = std::fs::read(data)?;
94 let size = data.len();
95 self.files.insert(name.to_string(), data);
96 Ok(size)
97 }
98}
99
100pub fn extract(input: &Path, output: &Path) -> Result<(), Ra2Error> {
114 let xcc = MixPackage::load(input, &MixDatabase::default())?;
115 let file_map = xcc.files;
116 std::fs::create_dir_all(output)?;
117 for (filename, file_data) in file_map {
118 let file_path = output.join(filename);
119 let mut file = File::create(file_path)?;
120 file.write_all(&file_data)?;
121 }
122 Ok(())
123}
124pub fn patch(input: &Path, output: &Path) -> Result<(), Ra2Error> {
138 let mut xcc = MixPackage::load(input, &MixDatabase::default())?;
139 for entry in std::fs::read_dir(input)? {
140 let entry = entry?;
141 xcc.add_file(&entry.path())?;
142 }
143 xcc.save(output)?;
144 Ok(())
145}