From 60a3eef4e510e76da2db9064b2555cd05317a928 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 11 Apr 2024 13:10:18 -0400 Subject: [PATCH] Added RemoveUnused mod example --- .../RemoveUnused/asset_sprites.meta.json | 12 +++++ .../RemoveUnused/asset_textures_2d.meta.json | 12 +++++ mods/assets/examples/RemoveUnused/meta.json | 5 ++ tools/Makefile | 3 +- .../helpers/fileHelper.cpp | 6 +++ .../dkr_assets_tool_src/helpers/fileHelper.h | 1 + .../helpers/jsonHelper.cpp | 54 ++++++++++++++++++- .../dkr_assets_tool_src/helpers/jsonHelper.h | 4 +- .../prebuild/compileAssets/compile.cpp | 4 +- .../prebuild/makeIncludes/assetEnums.cpp | 13 +++++ 10 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 mods/assets/examples/RemoveUnused/asset_sprites.meta.json create mode 100644 mods/assets/examples/RemoveUnused/asset_textures_2d.meta.json create mode 100644 mods/assets/examples/RemoveUnused/meta.json diff --git a/mods/assets/examples/RemoveUnused/asset_sprites.meta.json b/mods/assets/examples/RemoveUnused/asset_sprites.meta.json new file mode 100644 index 00000000..76fd0cd0 --- /dev/null +++ b/mods/assets/examples/RemoveUnused/asset_sprites.meta.json @@ -0,0 +1,12 @@ +{ + "files" : { + "sections" : { + "ASSET_SPRITE_MINIMAP_UNUSED" : { + "filename": null + }, + "ASSET_SPRITE_MINIMAP_UNUSED2" : { + "filename": null + } + } + } +} \ No newline at end of file diff --git a/mods/assets/examples/RemoveUnused/asset_textures_2d.meta.json b/mods/assets/examples/RemoveUnused/asset_textures_2d.meta.json new file mode 100644 index 00000000..98359da7 --- /dev/null +++ b/mods/assets/examples/RemoveUnused/asset_textures_2d.meta.json @@ -0,0 +1,12 @@ +{ + "files": { + "sections": { + "ASSET_TEX2D_MINIMAP_UNUSED": { + "filename": null + }, + "ASSET_TEX2D_MINIMAP_UNUSED2": { + "filename": null + } + } + } +} \ No newline at end of file diff --git a/mods/assets/examples/RemoveUnused/meta.json b/mods/assets/examples/RemoveUnused/meta.json new file mode 100644 index 00000000..70f6023c --- /dev/null +++ b/mods/assets/examples/RemoveUnused/meta.json @@ -0,0 +1,5 @@ +{ + "name": "Remove Unused Assets", + "authors" : ["Example"], + "description": "A simple example of how to remove assets by setting the section filename to null." +} \ No newline at end of file diff --git a/tools/Makefile b/tools/Makefile index d562bd75..6bcc6b04 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,6 +1,5 @@ - +# Make `OPT` -g for better debugging info. OPT := -O2 - CC := gcc CXX := g++ CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 $(OPT) -s diff --git a/tools/dkr_assets_tool_src/helpers/fileHelper.cpp b/tools/dkr_assets_tool_src/helpers/fileHelper.cpp index 32d6cd89..db48de15 100644 --- a/tools/dkr_assets_tool_src/helpers/fileHelper.cpp +++ b/tools/dkr_assets_tool_src/helpers/fileHelper.cpp @@ -311,6 +311,12 @@ void FileHelper::delete_directory(const fs::path &path) { } } +void FileHelper::delete_file(const fs::path &path) { + if(fs::exists(path)) { + fs::remove(path); + } +} + void FileHelper::rename(const fs::path &oldPath, const fs::path &newPath) { fs::rename(oldPath, newPath); } diff --git a/tools/dkr_assets_tool_src/helpers/fileHelper.h b/tools/dkr_assets_tool_src/helpers/fileHelper.h index 7f411adb..142b4bfd 100644 --- a/tools/dkr_assets_tool_src/helpers/fileHelper.h +++ b/tools/dkr_assets_tool_src/helpers/fileHelper.h @@ -54,6 +54,7 @@ public: static fs::path get_directory(const fs::path &path); static void delete_directory(const fs::path &path); + static void delete_file(const fs::path &path); static void rename(const fs::path &oldPath, const fs::path &newPath); static void copy(const fs::path &oldPath, const fs::path &newPath, bool recursive = false); diff --git a/tools/dkr_assets_tool_src/helpers/jsonHelper.cpp b/tools/dkr_assets_tool_src/helpers/jsonHelper.cpp index 66b85afa..26675e17 100644 --- a/tools/dkr_assets_tool_src/helpers/jsonHelper.cpp +++ b/tools/dkr_assets_tool_src/helpers/jsonHelper.cpp @@ -9,6 +9,8 @@ #include "helpers/debugHelper.h" #include "helpers/stringHelper.h" +#include "misc/settings.hpp" + // TODO: Support RapidJSON #include "libs/json.hpp" // nlohmann JSON library. (https://github.com/nlohmann/json) @@ -415,6 +417,54 @@ void json_merge_append(json &dst, json &patch) { } } +/******************************************************************/ + +void json_delete_file(DkrAssetsSettings &settings, json &dst, std::string filename) { + fs::path pathToAssets = settings.pathToAssets / settings.dkrVersion; + std::string folder = dst[json::json_pointer("/folder")]; + fs::path fileToDelete = pathToAssets / folder / filename; + + DebugHelper::info_verbose("Deleting file: ", fileToDelete); + + FileHelper::delete_file(fileToDelete); +} + +#define _JSON_HAS_KEY(json, key) (json.find(key) != json.end()) + +void json_check_for_removed_file_sections(DkrAssetsSettings &settings, json &dst, json &patch) { + json &order = dst[json::json_pointer("/files/order")]; + json §ions = dst[json::json_pointer("/files/sections")]; + json &patchSections = patch[json::json_pointer("/files/sections")]; + + if(!order.is_array() || !sections.is_object() || !patchSections.is_object()) { + // Not the correct json type, so don't bother! + return; + } + + size_t index = 0; + + while(index < order.size()) { + std::string key = order[index]; + if(_JSON_HAS_KEY(patchSections, key)) { // Check if the section id exists in the patch + json §ion = sections.at(key); + json &patchSection = patchSections.at(key); + if(_JSON_HAS_KEY(section, "filename") && _JSON_HAS_KEY(patchSection, "filename")) { // Make sure both the patch & dst have a filename. + if(!section.at("filename").is_null() && patchSection.at("filename").is_null()) { // Check if the filename becomes null + json_delete_file(settings, dst, section.at("filename")); // Delete the file if it exists. + order.erase(order.begin() + index); // Erase the index from the order. + sections.erase(key); // Erase the section. + continue; + } + } + } + index++; + } +} + +#undef _JSON_HAS_KEY + +/******************************************************************/ + enum JsonMergeType { MERGE_PATCH, // RFC 7386 - Arrays get overwritten. MERGE_APPEND // Like MERGE_PATCH, but arrays get appended to. @@ -430,7 +480,7 @@ const std::string DEFAULT_PATCH_TYPE = "patch-append"; /******************************************************************/ -void JsonHelper::patch_json(const fs::path &dstPath, const fs::path &patchPath) { +void JsonHelper::patch_json(DkrAssetsSettings &settings, const fs::path &dstPath, const fs::path &patchPath) { JsonFile *dstJsonFile = _load_json_from_cache(dstPath); JsonFile *patchJsonFile = _load_json_from_cache(patchPath); @@ -443,6 +493,8 @@ void JsonHelper::patch_json(const fs::path &dstPath, const fs::path &patchPath) JSON_HELPER_DETAILS::JsonFileData *dstJson = dstJsonFile->get_data(); JSON_HELPER_DETAILS::JsonFileData *patchJson = patchJsonFile->get_data(); + json_check_for_removed_file_sections(settings, dstJson->data, patchJson->data); + switch(mergeType) { case JsonMergeType::MERGE_PATCH: // RFC 7386 // Arrays will get overwritten. diff --git a/tools/dkr_assets_tool_src/helpers/jsonHelper.h b/tools/dkr_assets_tool_src/helpers/jsonHelper.h index 92f00c4b..3609120e 100644 --- a/tools/dkr_assets_tool_src/helpers/jsonHelper.h +++ b/tools/dkr_assets_tool_src/helpers/jsonHelper.h @@ -106,6 +106,8 @@ class StatJsonFile { JSON_HELPER_DETAILS::JsonFileData *_data; }; +class DkrAssetsSettings; + /** * Singleton class that deals with saving & loading json files. */ @@ -117,7 +119,7 @@ public: } bool get_file(fs::path filepath, JsonFile **out); - void patch_json(const fs::path &dst, const fs::path &patch); + void patch_json(DkrAssetsSettings &settings, const fs::path &dst, const fs::path &patch); private: std::unordered_map _fileCache; diff --git a/tools/dkr_assets_tool_src/prebuild/compileAssets/compile.cpp b/tools/dkr_assets_tool_src/prebuild/compileAssets/compile.cpp index 3ddef8df..060a107b 100644 --- a/tools/dkr_assets_tool_src/prebuild/compileAssets/compile.cpp +++ b/tools/dkr_assets_tool_src/prebuild/compileAssets/compile.cpp @@ -5,7 +5,7 @@ CompileAssets::CompileAssets(DkrAssetsSettings &settings) : _settings(settings) { _vanillaAssetsPath = _settings.pathToAssets / ".vanilla" / settings.dkrVersion; - _outAssetsPath = _settings.pathToAssets / settings.dkrVersion; + _outAssetsPath = _settings.pathToAssets / _settings.dkrVersion; _statFile = new StatJsonFile(_settings.pathToCache / "compileAssetsCache.json"); @@ -210,7 +210,7 @@ void CompileAssets::_merge_or_copy_file(fs::path &modDir, fs::path &path) { if(copyFile) { FileHelper::copy(modPath, outPath); } else { // Merge file - JsonHelper::get().patch_json(outPath, modPath); + JsonHelper::get().patch_json(_settings, outPath, modPath); } } \ No newline at end of file diff --git a/tools/dkr_assets_tool_src/prebuild/makeIncludes/assetEnums.cpp b/tools/dkr_assets_tool_src/prebuild/makeIncludes/assetEnums.cpp index 23db4c1f..1515d8bd 100644 --- a/tools/dkr_assets_tool_src/prebuild/makeIncludes/assetEnums.cpp +++ b/tools/dkr_assets_tool_src/prebuild/makeIncludes/assetEnums.cpp @@ -85,6 +85,12 @@ void AssetEnums::_write_single_asset_section_enums(const std::string §ionId, if(!fontSubfolder.empty()) { fontJsonPath /= fontSubfolder; } + + if(sectionJson->is_value_null("/filename")) { + _cHeader.write_comment("No file"); + return; + } + fontJsonPath /= sectionJson->get_string("/filename"); JsonFile *fontsJson; DebugHelper::assert(JsonHelper::get().get_file(fontJsonPath, &fontsJson), @@ -140,7 +146,14 @@ void AssetEnums::_write_deferred_asset_section_enums(const std::string §ionI std::vector sectionOrder; fromSectionJson->get_array("/files/order", sectionOrder); + std::string sectionPtr = "/files/sections/"; + for(std::string &assetBuildId : sectionOrder) { + // Don't include files that have null filenames. + if(fromSectionJson->is_value_null(sectionPtr + assetBuildId + "/filename")) { + continue; + } + // TODO: This only works for LevelNames. // Will need to be modified later since Object Animations aren't one-to-one with Object Models. sectionEnum.add_symbol(assetBuildId + idPostfix);