Recognise new Fallout 4 BA2 versions

This assumes that there are no relevant differences in how the new versions store file paths and hashes.
This commit is contained in:
Oliver Hamlet
2024-04-29 18:02:13 +01:00
parent 6dbe751727
commit 8a02621bb2
3 changed files with 50 additions and 2 deletions
+1
View File
@@ -36,6 +36,7 @@ set(LIBLOOT_SRC_TESTS_INTERNALS_CPP_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/main.cpp")
set(LIBLOOT_SRC_TESTS_INTERNALS_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/bsa_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/game/game_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/game/game_cache_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/game/load_order_handler_test.h"
+3 -2
View File
@@ -217,8 +217,9 @@ std::map<uint64_t, std::set<uint64_t>> GetAssetsInBA2(std::istream& in,
throw std::runtime_error("BA2 file header type ID is invalid");
}
// The header version is 1 for Fallout 4 and 2 or 3 for Starfield.
if (header.version != 1 && header.version != 2 && header.version != 3) {
// The header version is 1, 7 or 8 for Fallout 4 and 2 or 3 for Starfield.
if (header.version != 1 && header.version != 2 && header.version != 3 &&
header.version != 7 && header.version != 8) {
throw std::runtime_error("BA2 file header version is invalid");
}
+46
View File
@@ -27,6 +27,10 @@ along with LOOT. If not, see
#include <gtest/gtest.h>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <fstream>
#include "api/bsa.h"
namespace loot::test {
@@ -133,6 +137,48 @@ TEST(GetAssetsInBethesdaArchive, shouldSupportTextureBA2s) {
EXPECT_EQ(1, assets.find(folderHash)->second.count(fileHash));
}
class GetAssetsInBethesdaArchive_BA2Version
: public ::testing::TestWithParam<char> {
protected:
GetAssetsInBethesdaArchive_BA2Version() : path(GetArchivePath()) {
const auto sourcePath =
std::filesystem::u8path("./Fallout 4/Data/Blank - Main.ba2");
std::filesystem::copy(sourcePath, path);
std::fstream stream(
path, std::ios_base::binary | std::ios_base::in | std::ios_base::out);
stream.seekp(4);
stream.put(GetParam());
stream.close();
}
void TearDown() override { std::filesystem::remove(path); }
const std::filesystem::path path;
private:
std::filesystem::path GetArchivePath() {
const auto tempFilename =
"LOOT-test-" +
boost::lexical_cast<std::string>((boost::uuids::random_generator())()) +
".ba2";
return std::filesystem::temp_directory_path() / tempFilename;
}
};
// Pass an empty first argument, as it's a prefix for the test instantation,
// but we only have the one so no prefix is necessary.
INSTANTIATE_TEST_SUITE_P(,
GetAssetsInBethesdaArchive_BA2Version,
::testing::Values(1, 2, 3, 7, 8));
TEST_P(GetAssetsInBethesdaArchive_BA2Version, shouldSupportBA2Version) {
const auto assets = GetAssetsInBethesdaArchive(path);
EXPECT_FALSE(assets.empty());
}
TEST(GetAssetsInBethesdaArchives, shouldSkipFilesThatCannotBeRead) {
std::vector<std::filesystem::path> paths(
{std::filesystem::u8path("invalid.bsa"),