1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 15:19:42 +00:00

Merge branch 'bsatool' into 'master'

Add compressed BSA support to bsatool

See merge request OpenMW/openmw!366
This commit is contained in:
psi29a 2020-10-23 12:06:58 +00:00
commit f592aca6d3

View file

@ -6,7 +6,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <components/bsa/bsa_file.hpp> #include <components/bsa/compressedbsafile.hpp>
#include <components/misc/stringops.hpp>
#define BSATOOL_VERSION 1.1 #define BSATOOL_VERSION 1.1
@ -25,16 +26,6 @@ struct Arguments
bool fullpath; bool fullpath;
}; };
void replaceAll(std::string& str, const std::string& needle, const std::string& substitute)
{
size_t pos = str.find(needle);
while(pos != std::string::npos)
{
str.replace(pos, needle.size(), substitute);
pos = str.find(needle);
}
}
bool parseOptions (int argc, char** argv, Arguments &info) bool parseOptions (int argc, char** argv, Arguments &info)
{ {
bpo::options_description desc("Inspect and extract files from Bethesda BSA archives\n\n" bpo::options_description desc("Inspect and extract files from Bethesda BSA archives\n\n"
@ -144,9 +135,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return true; return true;
} }
int list(Bsa::BSAFile& bsa, Arguments& info); int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
int extract(Bsa::BSAFile& bsa, Arguments& info); int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
int extractAll(Bsa::BSAFile& bsa, Arguments& info); int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@ -157,8 +148,16 @@ int main(int argc, char** argv)
return 1; return 1;
// Open file // Open file
Bsa::BSAFile bsa; std::unique_ptr<Bsa::BSAFile> bsa;
bsa.open(info.filename);
Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(info.filename);
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
bsa = std::make_unique<Bsa::CompressedBSAFile>(Bsa::CompressedBSAFile());
else
bsa = std::make_unique<Bsa::BSAFile>(Bsa::BSAFile());
bsa->open(info.filename);
if (info.mode == "list") if (info.mode == "list")
return list(bsa, info); return list(bsa, info);
@ -179,10 +178,10 @@ int main(int argc, char** argv)
} }
} }
int list(Bsa::BSAFile& bsa, Arguments& info) int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
{ {
// List all files // List all files
const Bsa::BSAFile::FileList &files = bsa.getList(); const Bsa::BSAFile::FileList &files = bsa->getList();
for (const auto& file : files) for (const auto& file : files)
{ {
if(info.longformat) if(info.longformat)
@ -201,15 +200,15 @@ int list(Bsa::BSAFile& bsa, Arguments& info)
return 0; return 0;
} }
int extract(Bsa::BSAFile& bsa, Arguments& info) int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
{ {
std::string archivePath = info.extractfile; std::string archivePath = info.extractfile;
replaceAll(archivePath, "/", "\\"); Misc::StringUtils::replaceAll(archivePath, "/", "\\");
std::string extractPath = info.extractfile; std::string extractPath = info.extractfile;
replaceAll(extractPath, "\\", "/"); Misc::StringUtils::replaceAll(extractPath, "\\", "/");
if (!bsa.exists(archivePath.c_str())) if (!bsa->exists(archivePath.c_str()))
{ {
std::cout << "ERROR: file '" << archivePath << "' not found\n"; std::cout << "ERROR: file '" << archivePath << "' not found\n";
std::cout << "In archive: " << info.filename << std::endl; std::cout << "In archive: " << info.filename << std::endl;
@ -237,7 +236,7 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
} }
// Get a stream for the file to extract // Get a stream for the file to extract
Files::IStreamPtr stream = bsa.getFile(archivePath.c_str()); Files::IStreamPtr stream = bsa->getFile(archivePath.c_str());
bfs::ofstream out(target, std::ios::binary); bfs::ofstream out(target, std::ios::binary);
@ -250,12 +249,12 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
return 0; return 0;
} }
int extractAll(Bsa::BSAFile& bsa, Arguments& info) int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
{ {
for (const auto &file : bsa.getList()) for (const auto &file : bsa->getList())
{ {
std::string extractPath(file.name); std::string extractPath(file.name);
replaceAll(extractPath, "\\", "/"); Misc::StringUtils::replaceAll(extractPath, "\\", "/");
// Get the target path (the path the file will be extracted to) // Get the target path (the path the file will be extracted to)
bfs::path target (info.outdir); bfs::path target (info.outdir);
@ -273,7 +272,7 @@ int extractAll(Bsa::BSAFile& bsa, Arguments& info)
// Get a stream for the file to extract // Get a stream for the file to extract
// (inefficient because getFile iter on the list again) // (inefficient because getFile iter on the list again)
Files::IStreamPtr data = bsa.getFile(file.name); Files::IStreamPtr data = bsa->getFile(file.name);
bfs::ofstream out(target, std::ios::binary); bfs::ofstream out(target, std::ios::binary);
// Write the file to disk // Write the file to disk