diff --git a/src/Unlinker/ContentPrinter.cpp b/src/Unlinker/ContentPrinter.cpp new file mode 100644 index 00000000..7025f121 --- /dev/null +++ b/src/Unlinker/ContentPrinter.cpp @@ -0,0 +1,21 @@ +#include "ContentPrinter.h" + +ContentPrinter::ContentPrinter(Zone* zone) +{ + m_zone = zone; +} + +void ContentPrinter::PrintContent() const +{ + const ZoneContent content = m_zone->GetPools()->GetContent(); + + printf("Zone '%s' (%s)\n", m_zone->m_name.c_str(), content.m_game_name.c_str()); + puts("Content:"); + + for(const auto& asset : content.m_assets) + { + printf("%s, %s\n", asset.m_asset_type_name.c_str(), asset.m_asset_name.c_str()); + } + + puts(""); +} diff --git a/src/Unlinker/ContentPrinter.h b/src/Unlinker/ContentPrinter.h new file mode 100644 index 00000000..245095a5 --- /dev/null +++ b/src/Unlinker/ContentPrinter.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Zone/Zone.h" + +class ContentPrinter +{ + Zone* m_zone; + +public: + explicit ContentPrinter(Zone* zone); + + void PrintContent() const; +}; \ No newline at end of file diff --git a/src/Unlinker/main.cpp b/src/Unlinker/main.cpp index c96b7439..49efcecd 100644 --- a/src/Unlinker/main.cpp +++ b/src/Unlinker/main.cpp @@ -1,7 +1,11 @@ -#include #include "Utils/Arguments/ArgumentParser.h" #include "Utils/Arguments/UsageInformation.h" #include "ZoneLoading.h" +#include "ContentPrinter.h" +#include "Utils/PathUtils.h" + +#include +#include const CommandLineOption* optionHelp = CommandLineOption::Builder::Create() .WithShortName("?") @@ -51,6 +55,11 @@ void PrintUsage() usage.Print(); } +std::string ResolveOutputFolderPath(const std::string& path, Zone* zone) +{ + return std::regex_replace(path, std::regex("%zoneName%"), zone->m_name); +} + int main(const int argc, const char** argv) { ArgumentParser argumentParser(commandLineOptions, _countof(commandLineOptions)); @@ -75,6 +84,8 @@ int main(const int argc, const char** argv) return 1; } + std::vector loadedZones; + for(unsigned argIndex = 1; argIndex < argCount; argIndex++) { const std::string& zonePath = arguments[argIndex]; @@ -85,6 +96,51 @@ int main(const int argc, const char** argv) printf("Failed to load zone '%s'.\n", zonePath.c_str()); return 1; } + + loadedZones.push_back(zone); + } + + if(argumentParser.IsOptionSpecified(optionList)) + { + for(auto zone : loadedZones) + { + ContentPrinter printer(zone); + printer.PrintContent(); + } + } + else + { + const bool minimalisticZoneDefinition = argumentParser.IsOptionSpecified(optionMinimalZoneFile); + + for (auto zone : loadedZones) + { + std::string outputFolderPath; + + if (argumentParser.IsOptionSpecified(optionOutputFolder)) + { + outputFolderPath = ResolveOutputFolderPath(argumentParser.GetValueForOption(optionOutputFolder), zone); + } + else + { + outputFolderPath = ResolveOutputFolderPath("./%zoneName%", zone); + } + + FileAPI::CreateDirectory(outputFolderPath); + + FileAPI::File zoneDefinitionFile = FileAPI::Open(utils::Path::Combine(outputFolderPath, zone->m_name + ".zone"), FileAPI::Mode::MODE_WRITE); + + if(zoneDefinitionFile.IsOpen()) + { + ZoneLoading::WriteZoneDefinition(zone, &zoneDefinitionFile, minimalisticZoneDefinition); + ZoneLoading::DumpZone(zone, outputFolderPath); + } + else + { + printf("Failed to open file for zone definition file of zone '%s'.\n", zone->m_name.c_str()); + } + + zoneDefinitionFile.Close(); + } } return 0; diff --git a/src/ZoneCommon/Game/T6/GameAssetPoolT6.cpp b/src/ZoneCommon/Game/T6/GameAssetPoolT6.cpp index 9926082f..1247c0ca 100644 --- a/src/ZoneCommon/Game/T6/GameAssetPoolT6.cpp +++ b/src/ZoneCommon/Game/T6/GameAssetPoolT6.cpp @@ -334,4 +334,73 @@ void* GameAssetPoolT6::AddAsset(asset_type_t type, std::string name, void* asset return nullptr; #undef CASE_ADD_TO_POOL +} + +ZoneContent GameAssetPoolT6::GetContent() const +{ + ZoneContent content{}; + + content.m_game_name = "T6"; + +#define POOL_ADD_TO_CONTENT(assetTypeName, poolName) \ + if((poolName) != nullptr) \ + { \ + for(auto asset : *(poolName)) \ + { \ + content.m_assets.emplace_back((assetTypeName), asset->m_name);\ + } \ + } + + POOL_ADD_TO_CONTENT("physpreset", m_phys_preset); + POOL_ADD_TO_CONTENT("physconstraints", m_phys_constraints); + POOL_ADD_TO_CONTENT("destructibledef", m_destructible_def); + POOL_ADD_TO_CONTENT("xanim", m_xanim_parts); + POOL_ADD_TO_CONTENT("xmodel", m_xmodel); + POOL_ADD_TO_CONTENT("material", m_material); + POOL_ADD_TO_CONTENT("techniqueset", m_technique_set); + POOL_ADD_TO_CONTENT("image", m_image); + POOL_ADD_TO_CONTENT("soundbank", m_sound_bank); + POOL_ADD_TO_CONTENT("soundpatch", m_sound_patch); + POOL_ADD_TO_CONTENT("clipmap", m_clip_map); + POOL_ADD_TO_CONTENT("comworld", m_com_world); + POOL_ADD_TO_CONTENT("gameworldsp", m_game_world_sp); + POOL_ADD_TO_CONTENT("gameworldmp", m_game_world_mp); + POOL_ADD_TO_CONTENT("mapents", m_map_ents); + POOL_ADD_TO_CONTENT("gfxworld", m_gfx_world); + POOL_ADD_TO_CONTENT("gfxlightdef", m_gfx_light_def); + POOL_ADD_TO_CONTENT("font", m_font); + POOL_ADD_TO_CONTENT("fonticon", m_font_icon); + POOL_ADD_TO_CONTENT("menulist", m_menu_list); + POOL_ADD_TO_CONTENT("menudef", m_menu_def); + POOL_ADD_TO_CONTENT("localize", m_localize); + POOL_ADD_TO_CONTENT("weapon", m_weapon); + POOL_ADD_TO_CONTENT("attachment", m_attachment); + POOL_ADD_TO_CONTENT("attachmentunique", m_attachment_unique); + POOL_ADD_TO_CONTENT("camo", m_camo); + POOL_ADD_TO_CONTENT("snddriverglobals", m_snd_driver_globals); + POOL_ADD_TO_CONTENT("fx", m_fx); + POOL_ADD_TO_CONTENT("fximpacttable", m_fx_impact_table); + POOL_ADD_TO_CONTENT("rawfile", m_raw_file); + POOL_ADD_TO_CONTENT("stringtable", m_string_table); + POOL_ADD_TO_CONTENT("leaderboard", m_leaderboard); + POOL_ADD_TO_CONTENT("xglobals", m_xglobals); + POOL_ADD_TO_CONTENT("ddl", m_ddl); + POOL_ADD_TO_CONTENT("glasses", m_glasses); + POOL_ADD_TO_CONTENT("emblemset", m_emblem_set); + POOL_ADD_TO_CONTENT("script", m_script); + POOL_ADD_TO_CONTENT("keyvaluepairs", m_key_value_pairs); + POOL_ADD_TO_CONTENT("vehicle", m_vehicle); + POOL_ADD_TO_CONTENT("memoryblock", m_memory_block); + POOL_ADD_TO_CONTENT("addonmapents", m_addon_map_ents); + POOL_ADD_TO_CONTENT("tracer", m_tracer); + POOL_ADD_TO_CONTENT("skinnedverts", m_skinned_verts); + POOL_ADD_TO_CONTENT("qdb", m_qdb); + POOL_ADD_TO_CONTENT("slug", m_slug); + POOL_ADD_TO_CONTENT("footsteptable", m_footstep_table); + POOL_ADD_TO_CONTENT("footstepfxtable", m_footstep_fx_table); + POOL_ADD_TO_CONTENT("zbarrier", m_zbarrier); + + return content; + +#undef POOL_ADD_TO_CONTENT } \ No newline at end of file diff --git a/src/ZoneCommon/Game/T6/GameAssetPoolT6.h b/src/ZoneCommon/Game/T6/GameAssetPoolT6.h index 3cbfcd66..eb09e24e 100644 --- a/src/ZoneCommon/Game/T6/GameAssetPoolT6.h +++ b/src/ZoneCommon/Game/T6/GameAssetPoolT6.h @@ -65,4 +65,6 @@ public: void InitPoolDynamic(asset_type_t type) override; void* AddAsset(asset_type_t type, std::string name, void* asset, std::vector& scriptStrings, std::vector& dependencies) override; + + ZoneContent GetContent() const override; }; diff --git a/src/ZoneCommon/Pool/IZoneAssetPools.h b/src/ZoneCommon/Pool/IZoneAssetPools.h index f919df44..01be4b31 100644 --- a/src/ZoneCommon/Pool/IZoneAssetPools.h +++ b/src/ZoneCommon/Pool/IZoneAssetPools.h @@ -2,6 +2,7 @@ #include "XAssetInfo.h" #include "Zone/ZoneTypes.h" +#include "Zone/ZoneContent.h" class IZoneAssetPools { @@ -11,4 +12,5 @@ public: virtual void* AddAsset(asset_type_t type, std::string name, void* asset, std::vector& scriptStrings, std::vector& dependencies) = 0; virtual void InitPoolStatic(asset_type_t type, size_t capacity) = 0; virtual void InitPoolDynamic(asset_type_t type) = 0; -}; \ No newline at end of file + virtual ZoneContent GetContent() const = 0; +}; diff --git a/src/ZoneCommon/Zone/Zone.h b/src/ZoneCommon/Zone/Zone.h index 339cc7c1..909f1ac5 100644 --- a/src/ZoneCommon/Zone/Zone.h +++ b/src/ZoneCommon/Zone/Zone.h @@ -8,11 +8,11 @@ class IGame; class Zone { - std::string m_name; - zone_priority_t m_priority; IZoneAssetPools* m_pools; public: + std::string m_name; + zone_priority_t m_priority; IGame* m_game; Zone(std::string name, zone_priority_t priority, IZoneAssetPools* pools, IGame* game); diff --git a/src/ZoneCommon/Zone/ZoneContent.cpp b/src/ZoneCommon/Zone/ZoneContent.cpp new file mode 100644 index 00000000..63eada4d --- /dev/null +++ b/src/ZoneCommon/Zone/ZoneContent.cpp @@ -0,0 +1,13 @@ +#include "ZoneContent.h" + +ZoneContent::GameAsset::GameAsset(std::string assetTypeName, std::string assetName) +{ + m_asset_type_name = std::move(assetTypeName); + m_asset_name = std::move(assetName); +} + +ZoneContent::ZoneContent() +{ + m_game_name = ""; + m_assets = std::vector(); +} \ No newline at end of file diff --git a/src/ZoneCommon/Zone/ZoneContent.h b/src/ZoneCommon/Zone/ZoneContent.h new file mode 100644 index 00000000..b4b4d06f --- /dev/null +++ b/src/ZoneCommon/Zone/ZoneContent.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +class ZoneContent +{ +public: + class GameAsset + { + public: + GameAsset(std::string assetTypeName, std::string assetName); + + std::string m_asset_type_name; + std::string m_asset_name; + }; + + ZoneContent(); + + std::string m_game_name; + std::vector m_assets; +}; \ No newline at end of file diff --git a/src/ZoneLoading/ZoneLoading.cpp b/src/ZoneLoading/ZoneLoading.cpp index 9850db3c..106654d1 100644 --- a/src/ZoneLoading/ZoneLoading.cpp +++ b/src/ZoneLoading/ZoneLoading.cpp @@ -40,4 +40,14 @@ Zone* ZoneLoading::LoadZone(const std::string& path) file.Close(); return loadedZone; +} + +bool ZoneLoading::DumpZone(Zone* zone, const std::string& basePath) +{ + return true; +} + +bool ZoneLoading::WriteZoneDefinition(Zone* zone, FileAPI::File* file, bool minimalistic) +{ + return true; } \ No newline at end of file diff --git a/src/ZoneLoading/ZoneLoading.h b/src/ZoneLoading/ZoneLoading.h index 293bb4b0..68e55938 100644 --- a/src/ZoneLoading/ZoneLoading.h +++ b/src/ZoneLoading/ZoneLoading.h @@ -1,9 +1,12 @@ #pragma once #include "Zone/Zone.h" #include +#include "Utils/FileAPI.h" class ZoneLoading { public: static Zone* LoadZone(const std::string& path); + static bool DumpZone(Zone* zone, const std::string& basePath); + static bool WriteZoneDefinition(Zone* zone, FileAPI::File* file, bool minimalistic); };