From 5dbf7db274ca687956489be03a11c1bed5ef2e10 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Fri, 8 Jul 2022 17:34:31 -0500 Subject: [PATCH] Fix pak extractor. It now doesn't crash, and works with every pak file. --- README.md | 5 +++-- src/tools/jmmt_pack_extractor.cpp | 35 ++++++++++++++++++------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index a5fd4eb..9815e64 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,10 @@ Renames the .dat files in data/ on the disc to filenames which are actually usef ### `jmmt_pack_extractor` -Extractor for .pak files. Unlike the BMS script, this extractor takes into account several things about the format. +Extractor for .pak files. + +Unlike the BMS script, this extractor takes into account several things about the format. -Currently kind of crashy. Does extract a few archives in full though. ### `jmmt_met_extractor` diff --git a/src/tools/jmmt_pack_extractor.cpp b/src/tools/jmmt_pack_extractor.cpp index 7f7bbee..1cd410c 100644 --- a/src/tools/jmmt_pack_extractor.cpp +++ b/src/tools/jmmt_pack_extractor.cpp @@ -1,11 +1,11 @@ // Package file extractor. -// WIP, and a little crashy. // Yes, this code is messy, but I just wanted it to work after days of it not doing so. #include #include #include +#include #include #include #include @@ -125,25 +125,34 @@ struct PackageReader { // Setup some variables - // TODO: Implement CRC-based fallback, if required. - // It PROBABLY isn't. - - currFileName = crcToFilename[currChunk.filenameCrc]; - chunksLeft = currChunk.chunkAmount - 1; - // If we finished a file, the work buffer is empty. - if(fileWorkBuffer.empty()) + if(fileWorkBuffer.empty()) { + + // TODO: Implement CRC-based fallback, if required. + // It PROBABLY isn't. + + currFileName = crcToFilename[currChunk.filenameCrc]; + + std::cout << "Reading \"" << currFileName << "\".\n"; + + chunksLeft = currChunk.chunkAmount - 1; fileWorkBuffer.resize(currChunk.fileSize); + } std::vector compressedBuffer(currChunk.compressedChunkSize); auto old = is.tellg(); is.seekg(currChunk.dataOffset, std::istream::beg); - - // Read and decompress where we need to, taking the block offset into account. is.read(reinterpret_cast(compressedBuffer.data()), currChunk.compressedChunkSize); - jmmt::DecompressLzss(nullptr, compressedBuffer.data(), currChunk.compressedChunkSize, fileWorkBuffer.data() + currChunk.blockOffset); + + // If the chunk isn't actually compressed, just copy it into the work buffer. + // If it is, decompress it. + if(currChunk.compressedChunkSize == currChunk.chunkSize) { + memcpy(fileWorkBuffer.data() + currChunk.blockOffset, compressedBuffer.data(), currChunk.chunkSize); + } else { + jmmt::DecompressLzss(nullptr, compressedBuffer.data(), currChunk.compressedChunkSize, fileWorkBuffer.data() + currChunk.blockOffset); + } // Seek back to the old place the stream was before reading and decompress is.seekg(old, std::istream::beg); @@ -168,7 +177,7 @@ struct PackageReader { ReadFileChunk(); } - //std::cout << "Read file \"" << currFileName << "\"\n"; + std::cout << "Read file \"" << currFileName << "\"\n"; cb(DecompressedFile { .filename = currFileName, .data = fileWorkBuffer }); @@ -227,8 +236,6 @@ struct PackageReader { }; int main(int argc, char** argv) { - // std::ifstream ifs("config.pak", std::ifstream::binary); - if(argc != 2) { std::cout << "Usage: " << argv[0] << " [path 2 JMMT PAK file]"; return 1;