I’ve been putting this off for a while, but I’ve finally decided I’m going to add asset swapping. There’re a few existing implementations, so I’m reading those as well as some pdfs about the upk format. So basically credit to this document and this implementation. All it can do for now is parse the file summary.
The implementation wasn’t too bad since I had Google as well as the C# implementation I just talked about. I basically have
trait Deserializable: Sized {
fn deserialize(reader: &mut impl Read) -> AnyResult<Self>;
}
Then implement that for the various parts (eg. FGuid, a generic TArray). Then, I use byteorder to read out numbers into each struct. For example,
#[derive(Debug)]
struct FCompressedChunkInfo {
uncompressed_offset: i64,
uncompressed_size: i32,
compressed_offset: i64,
compressed_size: i32,
}
impl Deserializable for FCompressedChunkInfo {
fn deserialize(reader: &mut impl Read) -> AnyResult<Self> {
Ok(Self {
uncompressed_offset: reader.read_i64::<LittleEndian>()?,
uncompressed_size: reader.read_i32::<LittleEndian>()?,
compressed_offset: reader.read_i64::<LittleEndian>()?,
compressed_size: reader.read_i32::<LittleEndian>()?,
})
}
}
I originally prototyped it in Python and then moved to Rust once I got tired of python’s byte shenanigans.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.