From 2ff5fa303acd6ece18e1a3b47129692772784e88 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Sun, 16 Nov 2025 13:07:04 +0100 Subject: [PATCH 1/2] Initial fixed commit --- .../logic/luadefs/CLuaResourceDefs.cpp | 112 ++++++++++++++++++ .../logic/luadefs/CLuaResourceDefs.h | 13 ++ Server/mods/deathmatch/logic/CResourceFile.h | 1 + .../logic/luadefs/CLuaResourceDefs.cpp | 110 +++++++++++++++++ .../logic/luadefs/CLuaResourceDefs.h | 13 ++ 5 files changed, 249 insertions(+) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index 265c6383b1f..60930a037e6 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -11,6 +11,9 @@ #include "StdInc.h" #include +#include +#include +#include using std::list; @@ -26,6 +29,7 @@ void CLuaResourceDefs::LoadFunctions() {"getResourceGUIElement", GetResourceGUIElement}, {"getResourceDynamicElementRoot", GetResourceDynamicElementRoot}, {"getResourceExportedFunctions", GetResourceExportedFunctions}, + {"getResourceFiles", ArgumentParser}, {"getResourceState", GetResourceState}, {"loadstring", LoadString}, {"load", Load}, @@ -51,6 +55,7 @@ void CLuaResourceDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getConfig", "getResourceConfig"); lua_classfunction(luaVM, "getDynamicElementRoot", "getResourceDynamicElementRoot"); lua_classfunction(luaVM, "getExportedFunctions", "getResourceExportedFunctions"); + lua_classfunction(luaVM, "getFiles", "getResourceFiles"); lua_classfunction(luaVM, "getState", "getResourceState"); lua_classvariable(luaVM, "config", NULL, "getResourceConfig"); @@ -391,6 +396,113 @@ int CLuaResourceDefs::GetResourceExportedFunctions(lua_State* luaVM) return 1; } +namespace +{ + CLuaResourceDefs::eResourceFileFilter ParseFilterString(const std::string& strFilter) + { + std::string strLower = strFilter; + std::transform(strLower.begin(), strLower.end(), strLower.begin(), ::tolower); + + if (strLower == "map") + return CLuaResourceDefs::eResourceFileFilter::MAP; + else if (strLower == "script") + return CLuaResourceDefs::eResourceFileFilter::SCRIPT; + else if (strLower == "config") + return CLuaResourceDefs::eResourceFileFilter::CONFIG; + else if (strLower == "html") + return CLuaResourceDefs::eResourceFileFilter::HTML; + else if (strLower == "file") + return CLuaResourceDefs::eResourceFileFilter::FILE; + else + return CLuaResourceDefs::eResourceFileFilter::ALL; + } + + bool MatchesFilter(CDownloadableResource::eResourceType fileType, CLuaResourceDefs::eResourceFileFilter filter) + { + switch (filter) + { + case CLuaResourceDefs::eResourceFileFilter::ALL: + return true; + + case CLuaResourceDefs::eResourceFileFilter::MAP: + return fileType == CDownloadableResource::RESOURCE_FILE_TYPE_MAP; + + case CLuaResourceDefs::eResourceFileFilter::SCRIPT: + return fileType == CDownloadableResource::RESOURCE_FILE_TYPE_SCRIPT || + fileType == CDownloadableResource::RESOURCE_FILE_TYPE_CLIENT_SCRIPT; + + case CLuaResourceDefs::eResourceFileFilter::CONFIG: + return fileType == CDownloadableResource::RESOURCE_FILE_TYPE_CONFIG || + fileType == CDownloadableResource::RESOURCE_FILE_TYPE_CLIENT_CONFIG; + + case CLuaResourceDefs::eResourceFileFilter::HTML: + case CLuaResourceDefs::eResourceFileFilter::FILE: + return fileType == CDownloadableResource::RESOURCE_FILE_TYPE_HTML || + fileType == CDownloadableResource::RESOURCE_FILE_TYPE_CLIENT_FILE; + + default: + return false; + } + } +} + +std::variant, std::unordered_map>> +CLuaResourceDefs::GetResourceFiles(lua_State* luaVM, std::optional optResource, std::optional optIncludeAttributes, std::optional optFilter) +{ + CResource* pResource = optResource.value_or(nullptr); + bool bIncludeAttributes = optIncludeAttributes.value_or(false); + eResourceFileFilter filter = ParseFilterString(optFilter.value_or("all")); + + if (!pResource) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + pResource = pLuaMain->GetResource(); + } + } + + if (!pResource) + { + throw std::invalid_argument("Invalid resource"); + } + + if (bIncludeAttributes) + { + std::unordered_map> result; + + for (auto iter = pResource->IterBeginResourceFiles(); iter != pResource->IterEndResourceFiles(); ++iter) + { + CResourceFile* pResourceFile = *iter; + + if (!MatchesFilter(pResourceFile->GetResourceType(), filter)) + continue; + + std::unordered_map attrs; + + attrs["download"] = pResourceFile->IsAutoDownload() ? "true" : "false"; + + result[pResourceFile->GetShortName()] = attrs; + } + return result; + } + else + { + std::vector result; + + for (auto iter = pResource->IterBeginResourceFiles(); iter != pResource->IterEndResourceFiles(); ++iter) + { + CResourceFile* pResourceFile = *iter; + + if (!MatchesFilter(pResourceFile->GetResourceType(), filter)) + continue; + + result.push_back(pResourceFile->GetShortName()); + } + return result; + } +} + int CLuaResourceDefs::GetResourceState(lua_State* luaVM) { // string getResourceState ( resource theResource ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h index 38d3bc8ac61..f117e0b3892 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h @@ -26,6 +26,19 @@ class CLuaResourceDefs : public CLuaDefs LUA_DECLARE(GetResourceGUIElement); LUA_DECLARE(GetResourceDynamicElementRoot); LUA_DECLARE(GetResourceExportedFunctions); + + enum class eResourceFileFilter + { + ALL, + MAP, + SCRIPT, + CONFIG, + HTML, + FILE + }; + + static std::variant, std::unordered_map>> GetResourceFiles( + lua_State* luaVM, std::optional pResource, std::optional includeAttributes, std::optional filter); LUA_DECLARE(GetResourceState); LUA_DECLARE(LoadString); LUA_DECLARE(Load); diff --git a/Server/mods/deathmatch/logic/CResourceFile.h b/Server/mods/deathmatch/logic/CResourceFile.h index 4cfc3b36d06..5b756310fb5 100644 --- a/Server/mods/deathmatch/logic/CResourceFile.h +++ b/Server/mods/deathmatch/logic/CResourceFile.h @@ -69,5 +69,6 @@ class CResourceFile uint GetSizeHint() { return m_uiFileSizeHint; } // Only used by download counters string GetMetaFileAttribute(const string& key) { return m_attributeMap[key]; } + const map& GetAttributeMap() const { return m_attributeMap; } SString GetCachedPathFilename(bool bForceClientCachePath = false); }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index 58660c21ba0..84f677fa945 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -19,6 +19,9 @@ #include "CResourceConfigItem.h" #include "CDummy.h" #include "Utils.h" +#include +#include +#include extern CNetServer* g_pRealNetServer; @@ -60,6 +63,7 @@ void CLuaResourceDefs::LoadFunctions() {"getResourceMapRootElement", getResourceMapRootElement}, {"getResourceExportedFunctions", getResourceExportedFunctions}, {"getResourceOrganizationalPath", getResourceOrganizationalPath}, + {"getResourceFiles", ArgumentParser}, {"isResourceArchived", isResourceArchived}, {"isResourceProtected", ArgumentParser}, @@ -118,6 +122,7 @@ void CLuaResourceDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getDynamicElementRoot", "getResourceDynamicElementRoot"); lua_classfunction(luaVM, "getRootElement", "getResourceRootElement"); lua_classfunction(luaVM, "getExportedFunctions", "getResourceExportedFunctions"); + lua_classfunction(luaVM, "getFiles", "getResourceFiles"); lua_classfunction(luaVM, "getOrganizationalPath", "getResourceOrganizationalPath"); lua_classfunction(luaVM, "getLastStartTime", "getResourceLastStartTime"); lua_classfunction(luaVM, "getLoadTime", "getResourceLoadTime"); @@ -1068,6 +1073,111 @@ int CLuaResourceDefs::getResourceExportedFunctions(lua_State* luaVM) return 1; } +namespace +{ + CLuaResourceDefs::eResourceFileFilter ParseFilterString(const std::string& strFilter) + { + std::string strLower = strFilter; + std::transform(strLower.begin(), strLower.end(), strLower.begin(), ::tolower); + + if (strLower == "map") + return CLuaResourceDefs::eResourceFileFilter::MAP; + else if (strLower == "script") + return CLuaResourceDefs::eResourceFileFilter::SCRIPT; + else if (strLower == "config") + return CLuaResourceDefs::eResourceFileFilter::CONFIG; + else if (strLower == "html") + return CLuaResourceDefs::eResourceFileFilter::HTML; + else if (strLower == "file") + return CLuaResourceDefs::eResourceFileFilter::FILE; + else + return CLuaResourceDefs::eResourceFileFilter::ALL; + } + + bool MatchesFilter(CResourceFile::eResourceType fileType, CLuaResourceDefs::eResourceFileFilter filter) + { + switch (filter) + { + case CLuaResourceDefs::eResourceFileFilter::ALL: + return true; + + case CLuaResourceDefs::eResourceFileFilter::MAP: + return fileType == CResourceFile::RESOURCE_FILE_TYPE_MAP; + + case CLuaResourceDefs::eResourceFileFilter::SCRIPT: + return fileType == CResourceFile::RESOURCE_FILE_TYPE_SCRIPT || + fileType == CResourceFile::RESOURCE_FILE_TYPE_CLIENT_SCRIPT; + + case CLuaResourceDefs::eResourceFileFilter::CONFIG: + return fileType == CResourceFile::RESOURCE_FILE_TYPE_CONFIG || + fileType == CResourceFile::RESOURCE_FILE_TYPE_CLIENT_CONFIG; + + case CLuaResourceDefs::eResourceFileFilter::HTML: + case CLuaResourceDefs::eResourceFileFilter::FILE: + return fileType == CResourceFile::RESOURCE_FILE_TYPE_HTML || + fileType == CResourceFile::RESOURCE_FILE_TYPE_CLIENT_FILE; + + default: + return false; + } + } +} + +std::variant, std::unordered_map>> +CLuaResourceDefs::getResourceFiles(lua_State* luaVM, std::optional optResource, std::optional optIncludeAttributes, std::optional optFilter) +{ + CResource* pResource = optResource.value_or(nullptr); + bool bIncludeAttributes = optIncludeAttributes.value_or(false); + eResourceFileFilter filter = ParseFilterString(optFilter.value_or("all")); + + if (!pResource) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + pResource = pLuaMain->GetResource(); + } + } + + if (!pResource) + { + throw std::invalid_argument("Invalid resource"); + } + + if (bIncludeAttributes) + { + std::unordered_map> result; + + for (auto iter = pResource->IterBegin(); iter != pResource->IterEnd(); ++iter) + { + CResourceFile* pResourceFile = *iter; + + if (!MatchesFilter(pResourceFile->GetType(), filter)) + continue; + + const std::map& attributeMap = pResourceFile->GetAttributeMap(); + std::unordered_map attrs(attributeMap.begin(), attributeMap.end()); + result[pResourceFile->GetName()] = attrs; + } + return result; + } + else + { + std::vector result; + + for (auto iter = pResource->IterBegin(); iter != pResource->IterEnd(); ++iter) + { + CResourceFile* pResourceFile = *iter; + + if (!MatchesFilter(pResourceFile->GetType(), filter)) + continue; + + result.push_back(pResourceFile->GetName()); + } + return result; + } +} + int CLuaResourceDefs::getResourceOrganizationalPath(lua_State* luaVM) { // string getResourceOrganizationalPath ( resource theResource ) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h index 69524ece50e..734d37249f9 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.h @@ -52,6 +52,19 @@ class CLuaResourceDefs : public CLuaDefs LUA_DECLARE(getResourceMapRootElement); LUA_DECLARE(getResourceExportedFunctions); LUA_DECLARE(getResourceOrganizationalPath); + + enum class eResourceFileFilter + { + ALL, + MAP, + SCRIPT, + CONFIG, + HTML, + FILE + }; + + static std::variant, std::unordered_map>> getResourceFiles( + lua_State* luaVM, std::optional pResource, std::optional includeAttributes, std::optional filter); LUA_DECLARE(isResourceArchived); static std::string GetResourceName(lua_State* luaVM, std::optional resourceElement); From 72400993f95733e8f1157365a9c98e56e103f12b Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Mon, 17 Nov 2025 14:28:37 +0100 Subject: [PATCH 2/2] Refactor: Use trailing return type for ParseFilterString --- Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp | 2 +- Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index 60930a037e6..3b99b00df51 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -398,7 +398,7 @@ int CLuaResourceDefs::GetResourceExportedFunctions(lua_State* luaVM) namespace { - CLuaResourceDefs::eResourceFileFilter ParseFilterString(const std::string& strFilter) + auto ParseFilterString(const std::string& strFilter) -> CLuaResourceDefs::eResourceFileFilter { std::string strLower = strFilter; std::transform(strLower.begin(), strLower.end(), strLower.begin(), ::tolower); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp index 84f677fa945..75dfa0b87b0 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaResourceDefs.cpp @@ -1075,7 +1075,7 @@ int CLuaResourceDefs::getResourceExportedFunctions(lua_State* luaVM) namespace { - CLuaResourceDefs::eResourceFileFilter ParseFilterString(const std::string& strFilter) + auto ParseFilterString(const std::string& strFilter) -> CLuaResourceDefs::eResourceFileFilter { std::string strLower = strFilter; std::transform(strLower.begin(), strLower.end(), strLower.begin(), ::tolower);