diff --git a/patterns/lcesave.hexpat b/patterns/lcesave.hexpat index 3c940aab..7eeee9a3 100644 --- a/patterns/lcesave.hexpat +++ b/patterns/lcesave.hexpat @@ -1,17 +1,16 @@ #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; +#ifdef __IMHEX__ +import hex.core; +#endif #pragma pattern_limit 1000000 #pragma array_limit 1000000 @@ -51,8 +50,12 @@ 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 + #ifdef __IMHEX__ + hex::core::add_virtual_file(std::string::to_string(filename), file); + #endif } [[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,31 @@ 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; + #ifdef __IMHEX__ + hex::core::add_virtual_file("save", decompressed); + #endif + 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