From d20b05c7fbf1b198b43b89bd6844db43230ff538 Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 8 Feb 2023 21:53:44 +0100 Subject: [PATCH] Support reading specific nif files from archive by niftest --- apps/niftest/niftest.cpp | 45 ++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index 9f3f8066c6..21f40de86f 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -59,6 +59,15 @@ std::unique_ptr makeBsaArchive(const std::filesystem::path& path) return nullptr; } +std::unique_ptr makeArchive(const std::filesystem::path& path) +{ + if (isBSA(path)) + return makeBsaArchive(path); + if (std::filesystem::is_directory(path)) + return std::make_unique(path); + return nullptr; +} + /// Check all the nif files in a given VFS::Archive /// \note Can not read a bsa file inside of a bsa file. void readVFS(std::unique_ptr&& anArchive, const std::filesystem::path& archivePath = {}) @@ -98,7 +107,8 @@ void readVFS(std::unique_ptr&& anArchive, const std::filesystem::p } } -bool parseOptions(int argc, char** argv, std::vector& files, bool& writeDebugLog) +bool parseOptions(int argc, char** argv, std::vector& files, bool& writeDebugLog, + std::vector& archives) { bpo::options_description desc(R"(Ensure that OpenMW can use the provided NIF and BSA files @@ -110,6 +120,7 @@ Allowed options)"); auto addOption = desc.add_options(); addOption("help,h", "print help message."); addOption("write-debug-log,v", "write debug log for unsupported nif files"); + addOption("archives", bpo::value(), "path to archive files to provide files"); addOption("input-file", bpo::value(), "input file"); // Default option if none provided @@ -131,6 +142,8 @@ Allowed options)"); if (variables.count("input-file")) { files = variables["input-file"].as(); + if (const auto it = variables.find("archives"); it != variables.end()) + archives = it->second.as(); return true; } } @@ -149,12 +162,25 @@ int main(int argc, char** argv) { std::vector files; bool writeDebugLog = false; - if (!parseOptions(argc, argv, files, writeDebugLog)) + std::vector archives; + if (!parseOptions(argc, argv, files, writeDebugLog, archives)) return 1; Nif::Reader::setLoadUnsupportedFiles(true); Nif::Reader::setWriteNifDebugLog(writeDebugLog); + std::unique_ptr vfs; + if (!archives.empty()) + { + vfs = std::make_unique(true); + for (const std::filesystem::path& path : archives) + if (auto archive = makeArchive(path)) + vfs->addArchive(std::move(archive)); + else + std::cerr << '"' << path << "\" is unsupported archive" << std::endl; + vfs->buildIndex(); + } + // std::cout << "Reading Files" << std::endl; for (const auto& path : files) { @@ -165,17 +191,14 @@ int main(int argc, char** argv) // std::cout << "Decoding: " << name << std::endl; Nif::NIFFile file(path); Nif::Reader reader(file); - reader.parse(Files::openConstrainedFileStream(path)); + if (vfs != nullptr) + reader.parse(vfs->get(Files::pathToUnicodeString(path))); + else + reader.parse(Files::openConstrainedFileStream(path)); } - else if (isBSA(path)) + else if (auto archive = makeArchive(path)) { - // std::cout << "Reading BSA File: " << name << std::endl; - readVFS(makeBsaArchive(path)); - } - else if (std::filesystem::is_directory(path)) - { - // std::cout << "Reading All Files in: " << name << std::endl; - readVFS(std::make_unique(path), path); + readVFS(std::move(archive), path); } else {