Segunda versão

This commit is contained in:
Pedro de Oliveira 2022-11-07 18:23:46 +00:00
parent accc850281
commit 785eb00f46
2 changed files with 80 additions and 59 deletions

4
.gitignore vendored
View File

@ -1 +1,5 @@
/target
/EDEN.DAT
/losteden.iml
/NOVO.DAT
/.idea/

View File

@ -1,53 +1,71 @@
use std::io::SeekFrom;
use std::fs::File;
use std::io::{Read, Seek};
use byteorder::{LittleEndian, ReadBytesExt};
use std::fmt;
use std::io::{Read, Seek, Write};
// https://gist.github.com/falsovsky/da9a2de2c9a65282527fbd462bd92914
// https://github.com/scummvm/scummvm/blob/90f2ff2532ca71033b4393b9ce604c9b0e6cafa0/engines/cryo/defs.h#L761
// https://github.com/scummvm/scummvm/blob/master/engines/cryo/resource.cpp#L73
#[derive(Debug)]
struct DatHeader {
pub total: u16, // 2621 - Para obrigar os dados começarem a partir do offset 65536
pub files: Vec<DatFile>
}
impl DatHeader {
fn new(total: u16) -> Self {
Self { total, files: Vec::new() }
}
fn from_bytes(buffer: [u8; 2]) -> Self {
Self {
total: u16::from_le_bytes(buffer.try_into().expect("Slice with incorrect length")),
files: Vec::new()
}
}
fn to_bytes(&self) -> [u8; 2] {
self.total.to_le_bytes()
}
}
#[derive(Debug)]
struct DatFile {
name: [u8; 12],
unknown: [u8; 4],
size: [u8; 4],
offset: [u8; 4],
// 16 Bytes - Apenas 12 Bytes usados, resto com \0
pub name: String,
pub size: u32,
pub offset: u32,
pub flag: u8
}
impl fmt::Debug for DatFile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DatFile")
.field("name", &self.file_name())
.field("size", &self.file_size())
.field("offset", &self.file_offset())
.finish()
}
}
impl DatFile {
fn file_name(&self) -> &str {
std::str::from_utf8(&self.name).unwrap()
fn new(name: String, size: u32, offset: u32, flag: u8) -> Self {
Self {
name, size, offset, flag
}
}
fn file_size(&self) -> u32 {
let mut size_buf = &self.size[..];
size_buf.read_u32::<LittleEndian>().unwrap()
fn from_bytes(file_bytes: [u8; 25]) -> Self {
Self {
name: std::str::from_utf8(&file_bytes[0..16]).unwrap().to_string().replace('\0', ""),
size: u32::from_le_bytes(file_bytes[16..20].try_into().expect("Slice with incorrect length")),
offset: u32::from_le_bytes(file_bytes[20..24].try_into().expect("Slice with incorrect length")),
flag: file_bytes[24]
}
}
fn file_offset(&self) -> u32 {
let mut offset_buf = &self.offset[..];
offset_buf.read_u32::<LittleEndian>().unwrap()
}
}
struct Dat {
total: [u8; 2],
}
impl Dat {
fn get_value(&self) -> u16 {
let mut current = &self.total[..];
current.read_u16::<LittleEndian>().unwrap()
fn to_bytes(&self) -> [u8; 25] {
let mut file_bytes: [u8; 25] = [0; 25];
// name
if self.name.len() > 12 {
panic!("Filename invalido");
}
file_bytes[0..self.name.as_bytes().len()].clone_from_slice(self.name.as_bytes());
// size
file_bytes[16..20].clone_from_slice(&self.size.to_le_bytes());
// offset
file_bytes[20..24].clone_from_slice(&self.offset.to_le_bytes());
// flag
file_bytes[24] = self.flag;
file_bytes
}
}
@ -55,30 +73,29 @@ fn main() -> std::io::Result<()> {
let mut f = File::open("EDEN.DAT")?;
// Read Total Files
let mut buffer: [u8; 2] = [0; 2];
let _ = f.read(&mut buffer);
let dat = Dat{ total: buffer };
let mut file_dat: [u8; 2] = [0; 2];
let _ = f.read(&mut file_dat);
let mut dat = DatHeader::from_bytes(file_dat);
// Read File Name
let mut file_name: [u8; 12] = [0; 12];
let _ = f.read(&mut file_name);
println!("Valor: {:?} - Hex: {:02X?}", dat.total, dat.to_bytes());
// Skip 4 bytes
f.seek(SeekFrom::Current(4)).unwrap();
for _ in 0..dat.total {
let mut file_dat: [u8; 25] = [0; 25];
let _ = f.read(&mut file_dat);
// Read File Size
let mut file_size: [u8; 4] = [0; 4];
let _ = f.read(&mut file_size);
if file_dat[0] == 0 {
continue
}
let my_file = DatFile::from_bytes(file_dat);
println!("{:?} - {:02X?}", my_file, my_file.to_bytes());
dat.files.push(my_file);
}
// Read File Offset
let mut file_offset: [u8; 4] = [0; 4];
let _ = f.read(&mut file_offset);
let my_file: DatFile = DatFile{ name: file_name, size: file_size, offset: file_offset };
println!("{:?}", my_file);
println!("{:?}", dat.get_value());
let mut f = File::create("NOVO.DAT")?;
let _ = f.write(&dat.to_bytes());
for file in dat.files {
let _ = f.write(&file.to_bytes());
}
Ok(())
}