Skip to content

Commit

Permalink
use Virtual Filesystem + ZLib support + auto endian detection
Browse files Browse the repository at this point in the history
  • Loading branch information
DexrnZacAttack authored Oct 6, 2024
1 parent 1d66949 commit 875b37e
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions patterns/lcesave.hexpat
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
#pragma author DexrnZacAttack
#pragma description Decompressed Minecraft LCE Save File
#pragma description Minecraft LCE Save File

#pragma endian big
/* ^ switch this to little for Switch, PS4, or Xbox One */


// NOTE: This pattern was only tested on Nightly@974c4ba, things may break/not work on older versions.
// ALSO NOTE: SPEGHETTI CODE!

// TODO: re-add nbt pattern
// TODO: clean up getFileType
// NOTE: SPEGHETTI CODE!

import std.string;
import std.mem;
import std.core;
import hex.dec;
#pragma pattern_limit 1000000
#pragma array_limit 1000000

fn add_virtual_file(str path, auto pattern)
{
builtin::hex::core::add_virtual_file(path, pattern);
};

fn getFileType(str filename) {
// EWWWWWWW HOW DO I FIX THIS
match (std::string::substr(filename, std::string::length(filename) - 4, 4)) {
Expand Down Expand Up @@ -51,16 +52,40 @@ struct LCEIndex {
if (parent.header.curVersion > 1)
u64 timestamp [[name("File Timestamp")]]; // useless as it writes weirdly, and differently on certain consoles. (e.g using time since last reset, etc)
u8 file[filesize] @ offset [[name(this.filename),comment(getFileType(std::string::to_string(filename))),attribute_name(this.filename)]]; // files in the index
add_virtual_file(std::string::to_string(filename), file);
} [[name("(" + getFileType(std::string::to_string(filename)) + ") " + std::string::to_string(this.filename))]];


struct LCEHeader {
u32 offset [[name("Index Offset")]]; // where the index is located
u32 count [[name("Index File Count")]]; // amount of files in the index
u16 minVersion [[name("Minimum LCE file version")]]; // Minimum LCE version supported by file
u16 curVersion [[name("Current LCE file version")]]; // Version that the file was written with
};

struct CompressedSave {
be u64 zlibSize;
u8 zlibData[std::mem::size() - 8];
std::mem::Section zlib = std::mem::create_section(std::format("Compressed Save"));
hex::dec::zlib_decompress(zlibData, zlib, 15);
u8 decompressed[zlibSize] @ 0x00 in zlib;
add_virtual_file("save", decompressed);
std::error("This save is ZLib-compressed, grab the decompressed save from the Virtual Filesystem tab and use this pattern on it.");
};

struct LCESave {
u8 zlibMagic[2] @ 0x08 [[hidden]];
// check if header matches
if (zlibMagic[0] == 0x78 && zlibMagic[1] == 0x9C)
CompressedSave compSave @ 0x00;

// if not we will have continued.
le u16 endianCheck @ 0x0A [[hidden]];
// check if version is bigger than 14
if (endianCheck > 14)
std::core::set_endian(std::mem::Endian::Big);

// rest of the processing
LCEHeader header [[name("Header")]];
if (header.curVersion > 1)
LCEIndex index[header.count] @ header.offset [[name("File Index")]]; // the index
Expand Down

0 comments on commit 875b37e

Please sign in to comment.