Skip to content

Commit

Permalink
dump lua file and asset map in bo4 ff handler
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Feb 12, 2025
1 parent b9f39da commit 8bc3843
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
21 changes: 21 additions & 0 deletions src/acts/tools/ff/fastfile_dump.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

namespace fastfile::dump {
constexpr uint64_t BIN_MAGIC = 0x3054534c48415842;

struct BinXAssetListHeader {
uint64_t magic{ BIN_MAGIC };
uint64_t assetOffset{};
uint64_t assetCount{};
uint64_t stringsOffsetStart{};
uint64_t stringsOffsetEnd{};
uint64_t stringsCount{};
};

struct BinXAsset {
uint32_t type;
uint32_t idx;
uint64_t start;
uint64_t size;
};
}
3 changes: 3 additions & 0 deletions src/acts/tools/ff/fastfile_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ namespace fastfile {
else if (!_strcmpi("--assertContainer", arg)) {
assertContainer = true;
}
else if (!_strcmpi("--dumpBinaryAssetsMap", arg)) {
dumpBinaryAssetsMap = true;
}
else if (*arg == '-') {
std::cerr << "Invalid argument: " << arg << "!\n";
return false;
Expand Down
1 change: 1 addition & 0 deletions src/acts/tools/ff/fastfile_handlers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ namespace fastfile {
bool noAssetDump{};
bool assertContainer{};
bool dumpBinaryAssets{};
bool dumpBinaryAssetsMap{};
const char* m_casc{};
const char* game{};
const char* exec{};
Expand Down
75 changes: 68 additions & 7 deletions src/acts/tools/ff/handlers/handler_game_bo4.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <includes.hpp>
#include <tools/ff/fastfile_handlers.hpp>
#include <tools/ff/fastfile_dump.hpp>
#include <tools/utils/data_utils.hpp>
#include <hook/module_mapper.hpp>
#include <hook/memory.hpp>
Expand Down Expand Up @@ -217,7 +218,30 @@ namespace {
std::filesystem::path outFile{ bo4FFHandlerContext.opt->m_output / "bo4" / "source" / n };

std::filesystem::create_directories(outFile.parent_path());
LOG_INFO("Dump raw file {} {} 0x{:x}", outFile.string(), (void*)asset->buffer, asset->len);
LOG_INFO("Dump raw file {} 0x{:x}", outFile.string(), asset->len);
if (!utils::WriteFile(outFile, asset->buffer, asset->len)) {
LOG_ERROR("Error when dumping {}", outFile.string());
}
break;
}
case ASSET_TYPE_LUAFILE: {
struct LuaFile {
XHash name;
uint32_t len;
byte* buffer;
}; static_assert(sizeof(LuaFile) == 0x20);
LuaFile* asset{ (LuaFile*)xasset->header };

const char* n{ hashutils::ExtractPtr(asset->name.hash) };

if (!n) {
n = utils::va("hashed/%llx.lua", asset->name.hash);
}

std::filesystem::path outFile{ bo4FFHandlerContext.opt->m_output / "bo4" / "luafile" / n };

std::filesystem::create_directories(outFile.parent_path());
LOG_INFO("Dump lua file {} 0x{:x}", outFile.string(), asset->len);
if (!utils::WriteFile(outFile, asset->buffer, asset->len)) {
LOG_ERROR("Error when dumping {}", outFile.string());
}
Expand Down Expand Up @@ -374,6 +398,9 @@ namespace {

static char emptyStr[1]{};

std::vector<fastfile::dump::BinXAsset> assetMap{};
size_t stringsOffsetStart{ reader.Loc() };

if (assetList.stringsCount) {
//reader.Align<void*>();
assetList.strings = reader.ReadPtr<char*>(assetList.stringsCount);
Expand All @@ -388,6 +415,8 @@ namespace {
}
}
}
size_t stringsOffsetEnd{ reader.Loc() };

bo4FFHandlerContext.mtStrings.clear();
{
std::filesystem::path outStrings{ out / std::format("{}_strings.txt", ctx.ffname) };
Expand Down Expand Up @@ -426,27 +455,33 @@ namespace {
bo4FFHandlerContext.osassets = &osa;
bo4FFHandlerContext.loaded = 0;

std::filesystem::path bindir{ opt.m_output / "bo4" / "binary" };
std::filesystem::path binout{ bindir / ctx.ffname };
if (opt.dumpBinaryAssets) {
std::filesystem::create_directories(binout);
}
else if (opt.dumpBinaryAssetsMap) {
std::filesystem::create_directories(bindir);
}

for (size_t i = 0; i < assetList.assetCount; i++) {
XAsset_0& asset{ assetList.assets[i] };

const char* assType{ XAssetNameFromId(asset.type) };
LOG_DEBUG("Load asset {} (0x{:x})", assType, (int)asset.type);
std::filesystem::path binout{ opt.m_output / "bo4" / "binary" / ctx.ffname };
if (opt.dumpBinaryAssets) {
std::filesystem::create_directories(binout);
}


size_t originLoc{ bo4FFHandlerContext.Loc() };
bo4FFHandlerContext.Load_XAsset(false, &asset);
size_t endLoc{ bo4FFHandlerContext.Loc() };
size_t len{ bo4FFHandlerContext.Loc() - originLoc };

LOG_DEBUG("asset {} loaded (0x{:x}:0x{:x})", assType, originLoc, len);

if (opt.dumpBinaryAssets) {
std::vector<byte> rawAsset{};

utils::WriteValue(rawAsset, &asset, sizeof(asset));
reader.Goto(originLoc);
size_t len{ endLoc - originLoc };
utils::WriteValue(rawAsset, reader.ReadPtr<byte>(len), len);

std::filesystem::path assetOut{ binout / std::format("{:04}_{}.bin", i, assType) };
Expand All @@ -458,6 +493,32 @@ namespace {
LOG_ERROR("Error when dumping {}", assetOut.string());
}
}
if (opt.dumpBinaryAssetsMap) {
assetMap.emplace_back((uint32_t)asset.type, (uint32_t)i, originLoc, len);
}
}

if (opt.dumpBinaryAssetsMap) {
std::vector<byte> mapData{};

fastfile::dump::BinXAssetListHeader& header{ utils::Allocate<fastfile::dump::BinXAssetListHeader>(mapData) };
header.magic = fastfile::dump::BIN_MAGIC;
header.stringsCount = assetList.stringsCount;
header.stringsOffsetStart = stringsOffsetStart;
header.stringsOffsetEnd = stringsOffsetEnd;
header.assetOffset = mapData.size();
header.assetCount = assetMap.size();

utils::WriteValue(mapData, assetMap.data(), sizeof(assetMap[0]) * assetMap.size());

std::filesystem::path binmapout{ bindir / std::format("{}.map", ctx.ffname) };

if (utils::WriteFile(binmapout, mapData)) {
LOG_INFO("Dump asset {}", binmapout.string());
}
else {
LOG_ERROR("Error when dumping {}", binmapout.string());
}
}

LOG_INFO("{} asset(s) loaded (0x{:x})", bo4FFHandlerContext.loaded, bo4FFHandlerContext.loaded);
Expand Down

0 comments on commit 8bc3843

Please sign in to comment.