From 875b37e394408bbf3fcff8d92147bf44f4ceec1e Mon Sep 17 00:00:00 2001 From: Dexrn ZacAttack <60078656+DexrnZacAttack@users.noreply.github.com> Date: Sat, 5 Oct 2024 22:40:17 -0700 Subject: [PATCH] use Virtual Filesystem + ZLib support + auto endian detection --- patterns/lcesave.hexpat | 43 ++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/patterns/lcesave.hexpat b/patterns/lcesave.hexpat index 3c940aab..5c214844 100644 --- a/patterns/lcesave.hexpat +++ b/patterns/lcesave.hexpat @@ -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)) { @@ -51,8 +52,10 @@ 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 @@ -60,7 +63,29 @@ struct LCEHeader { 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