mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
* repo-wide: trim trailing spaces Note: This doesn't touch the .tbl files in encodings/ since they include meaningful trailing spaces (`20= `) * patterns: clean up duplicate semicolons * ELF: add header magic check * glTF: use type::Magic for magic value * glTF: check that the file size in the header matches * xgstexture: fix generics syntax for magic value * JPEG: define hex enum with 0x00 instead of 0X00 * CI: update deprecated actions --------- Co-authored-by: Nik <werwolv98@gmail.com>
99 lines
3.8 KiB
Rust
99 lines
3.8 KiB
Rust
#pragma author DexrnZacAttack
|
|
#pragma description Minecraft LCE Save File
|
|
|
|
|
|
// 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
|
|
|
|
fn getFileType(str filename) {
|
|
// EWWWWWWW HOW DO I FIX THIS
|
|
match (std::string::substr(filename, std::string::length(filename) - 4, 4)) {
|
|
(".mcr"):
|
|
if (std::string::starts_with(filename, "r."))
|
|
return "Overworld Region";
|
|
else if (std::string::starts_with(filename, "DIM-1"))
|
|
return "Nether Region";
|
|
else if (std::string::starts_with(filename, "DIM1"))
|
|
return "End Region";
|
|
else
|
|
return "Unknown Region";
|
|
(".dat"):
|
|
if (std::string::starts_with(filename, "players"))
|
|
return "Player";
|
|
else if (std::string::starts_with(filename, "data/")) {
|
|
if (std::string::starts_with(filename, "data/map_"))
|
|
return "Map File";
|
|
else
|
|
return "Other DAT File";
|
|
} else if (std::string::starts_with(filename, "level"))
|
|
return "Level File";
|
|
else
|
|
return "Unknown DAT";
|
|
|
|
(_): return "File";
|
|
}
|
|
};
|
|
|
|
struct LCEIndex {
|
|
char16 filename[0x40] [[name("File Name")]]; // name of the file.
|
|
u32 filesize [[name("File Size")]]; // how big the file is
|
|
u32 offset [[name("File Offset")]]; // where the file is located
|
|
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
|
|
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;
|
|
#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
|
|
else
|
|
LCEIndex index[header.count / 136] @ header.offset [[name("File Index")]]; // the index (pre-release)
|
|
} [[name("Save " + "(Version " + std::string::to_string(header.curVersion) + ")")]];
|
|
|
|
LCESave Save @ 0x00;
|