From c11dfd8422f9ba30f52c7b7bdd3cd4e0e93db807 Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Sun, 28 Jan 2024 18:38:46 +0100 Subject: [PATCH] Address review --- .../Modules/AssetInterfaces/IXModel.cpp | 2 - src/Components/Modules/ZoneBuilder.cpp | 270 +++++++++--------- src/Components/Modules/ZoneBuilder.hpp | 2 + 3 files changed, 142 insertions(+), 132 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index e508f570..ac22bc5e 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -1,7 +1,5 @@ #include -#include - #include "IXModel.hpp" namespace Assets diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index b0606ef4..455b0136 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -1167,6 +1167,139 @@ namespace Components return params; } + void ZoneBuilder::DumpZone(const std::string& zone) + { + ZoneBuilder::DumpingZone = zone; + ZoneBuilder::RefreshExporterWorkDirectory(); + + std::vector> assets{}; + const auto unload = ZoneBuilder::LoadZoneWithTrace(zone, assets); + + Logger::Print("Dumping zone '{}'...\n", zone); + + { + Utils::IO::CreateDir(GetDumpingZonePath()); + std::ofstream csv(std::filesystem::path(GetDumpingZonePath()) / std::format("{}.csv", zone)); + csv + << std::format("### Zone '{}' dumped with Zonebuilder {}", zone, Components::Branding::GetVersionString()) + << "\n\n"; + + // Order the CSV around + // TODO: Trim asset list using IW4OF dependencies + constexpr Game::XAssetType typeOrder[] = { + Game::XAssetType::ASSET_TYPE_GAMEWORLD_MP, + Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, + Game::XAssetType::ASSET_TYPE_GFXWORLD, + Game::XAssetType::ASSET_TYPE_COMWORLD, + Game::XAssetType::ASSET_TYPE_FXWORLD, + Game::XAssetType::ASSET_TYPE_CLIPMAP_MP, + Game::XAssetType::ASSET_TYPE_CLIPMAP_SP, + Game::XAssetType::ASSET_TYPE_RAWFILE, + Game::XAssetType::ASSET_TYPE_VEHICLE, + Game::XAssetType::ASSET_TYPE_WEAPON, + Game::XAssetType::ASSET_TYPE_FX, + Game::XAssetType::ASSET_TYPE_TRACER, + Game::XAssetType::ASSET_TYPE_XMODEL, + Game::XAssetType::ASSET_TYPE_MATERIAL, + Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, + Game::XAssetType::ASSET_TYPE_PIXELSHADER, + Game::XAssetType::ASSET_TYPE_VERTEXSHADER, + Game::XAssetType::ASSET_TYPE_VERTEXDECL, + Game::XAssetType::ASSET_TYPE_IMAGE, + Game::XAssetType::ASSET_TYPE_SOUND, + Game::XAssetType::ASSET_TYPE_LOADED_SOUND, + Game::XAssetType::ASSET_TYPE_SOUND_CURVE, + Game::XAssetType::ASSET_TYPE_PHYSPRESET, + }; + + std::unordered_map typePriority{}; + for (auto i = 0; i < ARRAYSIZE(typeOrder); i++) + { + const auto type = typeOrder[i]; + typePriority.emplace(type, 1 + ARRAYSIZE(typeOrder) - i); + } + + std::map> invalidAssets{}; + + std::sort(assets.begin(), assets.end(), [&]( + const std::pair& a, + const std::pair& b + ) { + if (a.first == b.first) + { + + return a.second.compare(b.second) < 0; + } + else + { + const auto priorityA = typePriority[a.first]; + const auto priorityB = typePriority[b.first]; + + if (priorityA == priorityB) + { + return a.second.compare(b.second) < 0; + } + else + { + return priorityB < priorityA; + } + } + }); + + // Used to format the CSV + Game::XAssetType lastTypeEncountered{}; + + for (const auto& asset : assets) + { + const auto type = asset.first; + const auto name = asset.second; + if (ExporterAPI.is_type_supported(type) && name[0] != ',') + { + const auto assetHeader = Game::DB_FindXAssetHeader(type, name.data()); + if (assetHeader.data) + { + ExporterAPI.write(type, assetHeader.data); + const auto typeName = Game::DB_GetXAssetTypeName(type); + + if (type != lastTypeEncountered) + { + csv << "\n### " << typeName << "\n"; + lastTypeEncountered = type; + } + + csv << typeName << "," << name << "\n"; + } + else + { + Logger::Warning(Game::conChannel_t::CON_CHANNEL_ERROR, "Asset {} has disappeared while dumping!\n", name); + invalidAssets["The following assets disappeared while dumping"].push_back(std::format("{},{}", Game::DB_GetXAssetTypeName(type), name)); + } + } + else + { + invalidAssets["The following assets are unsupported or not dumped as individual assets, but still present in the zone"].push_back(std::format("{},{}", Game::DB_GetXAssetTypeName(type), name)); + } + } + + for (const auto& kv : invalidAssets) + { + csv << "\n### " << kv.first << "\n"; + for (const auto& line : kv.second) + { + csv << "#" << line << "\n"; + } + } + + csv << std::format("\n### {} assets", assets.size()) << "\n"; + } + + unload(); + + Logger::Print("Zone '{}' dumped", ZoneBuilder::DumpingZone); + ZoneBuilder::DumpingZone = std::string(); + } + + std::function ZoneBuilder::LoadZoneWithTrace(const std::string& zone, OUT std::vector>& assets) { ZoneBuilder::BeginAssetTrace(zone); @@ -1193,7 +1326,7 @@ namespace Components Game::DB_LoadXAssets(&info, 1, true); AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_RAWFILE, "default"); // Lock until zone is unloaded - }; + }; } ZoneBuilder::ZoneBuilder() @@ -1320,132 +1453,7 @@ namespace Components std::string zone = params->get(1); - ZoneBuilder::DumpingZone = zone; - ZoneBuilder::RefreshExporterWorkDirectory(); - - std::vector> assets{}; - const auto unload = ZoneBuilder::LoadZoneWithTrace(zone, assets); - - Logger::Print("Dumping zone '{}'...\n", zone); - - { - Utils::IO::CreateDir(GetDumpingZonePath()); - std::ofstream csv(std::filesystem::path(GetDumpingZonePath()) / std::format("{}.csv", zone)); - csv - << std::format("### Zone '{}' dumped with Zonebuilder {}", zone, Components::Branding::GetVersionString()) - << "\n\n"; - - constexpr Game::XAssetType typeOrder[] = { - Game::XAssetType::ASSET_TYPE_GAMEWORLD_MP, - Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, - Game::XAssetType::ASSET_TYPE_GFXWORLD, - Game::XAssetType::ASSET_TYPE_COMWORLD, - Game::XAssetType::ASSET_TYPE_FXWORLD, - Game::XAssetType::ASSET_TYPE_CLIPMAP_MP, - Game::XAssetType::ASSET_TYPE_CLIPMAP_SP, - Game::XAssetType::ASSET_TYPE_RAWFILE, - Game::XAssetType::ASSET_TYPE_VEHICLE, - Game::XAssetType::ASSET_TYPE_WEAPON, - Game::XAssetType::ASSET_TYPE_FX, - Game::XAssetType::ASSET_TYPE_TRACER, - Game::XAssetType::ASSET_TYPE_XMODEL, - Game::XAssetType::ASSET_TYPE_MATERIAL, - Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, - Game::XAssetType::ASSET_TYPE_PIXELSHADER, - Game::XAssetType::ASSET_TYPE_VERTEXSHADER, - Game::XAssetType::ASSET_TYPE_VERTEXDECL, - Game::XAssetType::ASSET_TYPE_IMAGE, - Game::XAssetType::ASSET_TYPE_SOUND, - Game::XAssetType::ASSET_TYPE_LOADED_SOUND, - Game::XAssetType::ASSET_TYPE_SOUND_CURVE, - Game::XAssetType::ASSET_TYPE_PHYSPRESET, - }; - - std::unordered_map typePriority{}; - for (auto i = 0; i < ARRAYSIZE(typeOrder); i++) - { - const auto type = typeOrder[i]; - typePriority.emplace(type, 1 + ARRAYSIZE(typeOrder) - i); - } - - std::map> invalidAssets{}; - - std::sort(assets.begin(), assets.end(), [&]( - const std::pair& a, - const std::pair& b - ) { - if (a.first == b.first) - { - - return a.second.compare(b.second) < 0; - } - else - { - const auto priorityA = typePriority[a.first]; - const auto priorityB = typePriority[b.first]; - - if (priorityA == priorityB) - { - return a.second.compare(b.second) < 0; - } - else - { - return priorityB < priorityA; - } - } - }); - - // Used to format the CSV - Game::XAssetType lastTypeEncountered{}; - - for (const auto& asset : assets) - { - const auto type = asset.first; - const auto name = asset.second; - if (ExporterAPI.is_type_supported(type) && name[0] != ',') - { - const auto assetHeader = Game::DB_FindXAssetHeader(type, name.data()); - if (assetHeader.data) - { - ExporterAPI.write(type, assetHeader.data); - const auto typeName = Game::DB_GetXAssetTypeName(type); - - if (type != lastTypeEncountered) - { - csv << "\n### " << typeName << "\n"; - lastTypeEncountered = type; - } - - csv << typeName << "," << name << "\n"; - } - else - { - Logger::Warning(Game::conChannel_t::CON_CHANNEL_ERROR, "Asset {} has disappeared while dumping!\n", name); - invalidAssets["The following assets disappeared while dumping"].push_back(std::format("{},{}", Game::DB_GetXAssetTypeName(type), name)); - } - } - else - { - invalidAssets["The following assets are unsupported or not dumped as individual assets, but still present in the zone"].push_back(std::format("{},{}", Game::DB_GetXAssetTypeName(type), name)); - } - } - - for (const auto& kv : invalidAssets) - { - csv << "\n### " << kv.first << "\n"; - for (const auto& line : kv.second) - { - csv << "#" << line << "\n"; - } - } - - csv << std::format("\n### {} assets", assets.size()) << "\n"; - } - - unload(); - - Logger::Print("Zone '{}' dumped", ZoneBuilder::DumpingZone); - ZoneBuilder::DumpingZone = std::string(); + ZoneBuilder::DumpZone(zone); }); Command::Add("verifyzone", [](const Command::Params* params) @@ -1480,18 +1488,20 @@ namespace Components { if (params->size() < 2) return; + Dvar::Var fs_game("fs_game"); + std::string modName = params->get(1); Logger::Print("Building zone for mod '{}'...\n", modName); - const std::string previousFsGame = Dvar::Var("fs_game").get(); + const std::string previousFsGame = fs_game.get(); const std::string dir = "mods/" + modName; Utils::IO::CreateDir(dir); - Dvar::Var("fs_game").set(dir); + fs_game.set(dir); Zone("mod", modName, dir + "/mod.ff").build(); - Dvar::Var("fs_game").set(previousFsGame); + fs_game.set(previousFsGame); }); Command::Add("buildall", []() diff --git a/src/Components/Modules/ZoneBuilder.hpp b/src/Components/Modules/ZoneBuilder.hpp index 7fb5a05d..ad4a049b 100644 --- a/src/Components/Modules/ZoneBuilder.hpp +++ b/src/Components/Modules/ZoneBuilder.hpp @@ -162,6 +162,8 @@ namespace Components static iw4of::params_t GetExporterAPIParams(); + static void DumpZone(const std::string& zone); + static std::function LoadZoneWithTrace(const std::string& zone, OUT std::vector> &assets); static void Com_Quitf_t();