summaryrefslogtreecommitdiff
path: root/packer/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'packer/src/main.rs')
-rw-r--r--packer/src/main.rs170
1 files changed, 170 insertions, 0 deletions
diff --git a/packer/src/main.rs b/packer/src/main.rs
new file mode 100644
index 0000000..ae4e02a
--- /dev/null
+++ b/packer/src/main.rs
@@ -0,0 +1,170 @@
+use std::env;
+use std::{
+ fs::{self, File},
+ io::{BufReader, Read},
+};
+
+use byteorder::{ByteOrder, LittleEndian};
+use serde::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct ImportListElement {
+ pub extension: String,
+ pub index: u32,
+ pub name: String,
+ pub unknown0: u32,
+ pub unknown1: u32,
+ pub unknown2: u32,
+}
+
+#[derive(Debug)]
+pub struct ListElement {
+ pub extension: String,
+ pub index: u32,
+ pub name: String,
+ pub position: u32,
+ pub size: u32,
+ pub unknown0: u32,
+ pub unknown1: u32,
+ pub unknown2: u32,
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+
+ let input = &args[1];
+ let output = &args[2];
+
+ pack(String::from(input), String::from(output));
+}
+
+fn pack(input: String, output: String) {
+ // Загружаем индекс-файл
+ let index_file = format!("{}/{}", input, "index.json");
+ let data = fs::read_to_string(index_file).unwrap();
+ let list: Vec<ImportListElement> = serde_json::from_str(&data).unwrap();
+
+ // Общий буфер хранения файлов
+ let mut content_buffer: Vec<u8> = Vec::new();
+ let mut list_buffer: Vec<u8> = Vec::new();
+
+ // Общее количество файлов
+ let total_files: u32 = list.len() as u32;
+
+ for (index, item) in list.iter().enumerate() {
+ // Открываем дескриптор файла
+ let path = format!("{}/{}", input, item.name);
+ let file = File::open(path).unwrap();
+ let metadata = file.metadata().unwrap();
+
+ // Считываем файл в буфер
+ let mut reader = BufReader::new(file);
+ let mut file_buffer: Vec<u8> = Vec::new();
+ reader.read_to_end(&mut file_buffer).unwrap();
+
+ // Выравнивание буфера
+ if index != 0 {
+ while content_buffer.len() % 8 != 0 {
+ content_buffer.push(0);
+ }
+ }
+
+ // Получение позиции файла
+ let position = content_buffer.len() + 16;
+
+ // Записываем файл в буфер
+ content_buffer.extend(file_buffer);
+
+ // Формируем элемент
+ let element = ListElement {
+ extension: item.extension.to_string(),
+ index: item.index,
+ name: item.name.to_string(),
+ position: position as u32,
+ size: metadata.len() as u32,
+ unknown0: item.unknown0,
+ unknown1: item.unknown1,
+ unknown2: item.unknown2,
+ };
+
+ // Создаем буфер из элемента
+ let mut element_buffer: Vec<u8> = Vec::new();
+
+ // Пишем тип файла
+ let mut extension_buffer: [u8; 4] = [0; 4];
+ let mut file_extension_buffer = element.extension.into_bytes();
+ file_extension_buffer.resize(4, 0);
+ extension_buffer.copy_from_slice(&file_extension_buffer);
+ element_buffer.extend(extension_buffer);
+
+ // Пишем неизвестное значение #1
+ let mut unknown0_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut unknown0_buffer, element.unknown0);
+ element_buffer.extend(unknown0_buffer);
+
+ // Пишем неизвестное значение #2
+ let mut unknown1_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut unknown1_buffer, element.unknown1);
+ element_buffer.extend(unknown1_buffer);
+
+ // Пишем размер файла
+ let mut file_size_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut file_size_buffer, element.size);
+ element_buffer.extend(file_size_buffer);
+
+ // Пишем неизвестное значение #3
+ let mut unknown2_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut unknown2_buffer, element.unknown2);
+ element_buffer.extend(unknown2_buffer);
+
+ // Пишем название файла
+ let mut name_buffer: [u8; 36] = [0; 36];
+ let mut file_name_buffer = element.name.into_bytes();
+ file_name_buffer.resize(36, 0);
+ name_buffer.copy_from_slice(&file_name_buffer);
+ element_buffer.extend(name_buffer);
+
+ // Пишем позицию файла
+ let mut position_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut position_buffer, element.position);
+ element_buffer.extend(position_buffer);
+
+ // Пишем индекс файла
+ let mut index_buffer: [u8; 4] = [0; 4];
+ LittleEndian::write_u32(&mut index_buffer, element.index);
+ element_buffer.extend(index_buffer);
+
+ // Добавляем итоговый буфер в буфер элементов списка
+ list_buffer.extend(element_buffer);
+ }
+
+ let mut header_buffer: Vec<u8> = Vec::new();
+
+ // Пишем первый тип файла
+ let mut header_type_1 = [0; 4];
+ LittleEndian::write_u32(&mut header_type_1, 1936020046_u32);
+ header_buffer.extend(header_type_1);
+
+ // Пишем второй тип файла
+ let mut header_type_2 = [0; 4];
+ LittleEndian::write_u32(&mut header_type_2, 256_u32);
+ header_buffer.extend(header_type_2);
+
+ // Пишем количество файлов
+ let mut header_total_files = [0; 4];
+ LittleEndian::write_u32(&mut header_total_files, total_files);
+ header_buffer.extend(header_total_files);
+
+ // Пишем общий размер файла
+ let mut header_total_size = [0; 4];
+ let total_size: u32 = ((content_buffer.len() + 16) as u32) + (total_files * 64);
+ LittleEndian::write_u32(&mut header_total_size, total_size);
+ header_buffer.extend(header_total_size);
+
+ let mut result_buffer: Vec<u8> = Vec::new();
+ result_buffer.extend(header_buffer);
+ result_buffer.extend(content_buffer);
+ result_buffer.extend(list_buffer);
+
+ fs::write(output, result_buffer).unwrap();
+}