diff --git a/Server/mods/deathmatch/logic/CResource.AclRequest.cpp b/Server/mods/deathmatch/logic/CResource.AclRequest.cpp index d8a6a5a5aab..16fd39f9463 100644 --- a/Server/mods/deathmatch/logic/CResource.AclRequest.cpp +++ b/Server/mods/deathmatch/logic/CResource.AclRequest.cpp @@ -123,9 +123,6 @@ bool CResource::HasAutoPermissions(CXMLNode* pNodeAclRequest) /////////////////////////////////////////////////////////////// void CResource::RefreshAutoPermissions(CXMLNode* pNodeAclRequest) { - // Check if permissions already active - if (HasAutoPermissions(pNodeAclRequest)) - return; // Ensure group and acl exist CAccessControlListGroup* pAutoGroup = g_pGame->GetACLManager()->AddGroup(GetAutoGroupName()); @@ -372,3 +369,51 @@ bool CResource::FindAclRequest(SAclRequest& result) return pAclRight->GetAttributeValue("pending") != ""; } + +std::string CResource::CalculateACLRequestFingerprint() +{ + std::string strPath; + if (!GetFilePath("meta.xml", strPath)) + return {}; + + std::unique_ptr metaFile(g_pServerInterface->GetXML()->CreateXML(strPath.c_str())); + if (!metaFile || !metaFile->Parse()) + { + return {}; + } + + CXMLNode* root = metaFile->GetRootNode(); + if (!root) + { + return {}; + } + + std::ostringstream fingerprint; + CXMLNode* nodeAclRequest = root->FindSubNode("aclrequest", 0); + + if (nodeAclRequest) + { + for (std::uint8_t uiIndex = 0; true; uiIndex++) + { + CXMLNode* nodeRight = nodeAclRequest->FindSubNode("right", uiIndex); + if (!nodeRight) + break; + + std::string strName = nodeRight->GetAttributeValue("name"); + std::string strAccess = nodeRight->GetAttributeValue("access"); + + if (uiIndex > 0) + fingerprint << ";"; + + fingerprint << strName << ":" << strAccess; + } + } + + return fingerprint.str(); +} + +bool CResource::HasACLRequestsChanged() +{ + std::string strCurrentFingerprint = CalculateACLRequestFingerprint(); + return strCurrentFingerprint != m_strACLRequestFingerprint; +} diff --git a/Server/mods/deathmatch/logic/CResource.cpp b/Server/mods/deathmatch/logic/CResource.cpp index fa1fe5c2f53..59d0d29f7a4 100644 --- a/Server/mods/deathmatch/logic/CResource.cpp +++ b/Server/mods/deathmatch/logic/CResource.cpp @@ -196,6 +196,8 @@ bool CResource::Load() else RemoveAutoPermissions(); + m_strACLRequestFingerprint = CalculateACLRequestFingerprint(); + // Find any map sync option m_bSyncMapElementData = true; m_bSyncMapElementDataDefined = false; @@ -351,6 +353,7 @@ bool CResource::Unload() m_strResourceZip = ""; m_strResourceCachePath = ""; m_strResourceDirectoryPath = ""; + m_strACLRequestFingerprint.clear(); m_eState = EResourceState::None; return true; @@ -402,6 +405,8 @@ CResource::~CResource() void CResource::TidyUp() { + RemoveAutoPermissions(); + // Close the zipfile stuff if (m_zipfile) unzClose(m_zipfile); @@ -678,6 +683,11 @@ bool CResource::HasResourceChanged() return true; } + if (HasACLRequestsChanged()) + { + return true; + } + return false; } @@ -1195,6 +1205,9 @@ bool CResource::Stop(bool bManualStop) // Clear the list of players where this resource is running std::exchange(m_isRunningForPlayer, {}); + // Remove ACL permissions when stopping + RemoveAutoPermissions(); + OnResourceStateChange("loaded"); m_eState = EResourceState::Loaded; return true; diff --git a/Server/mods/deathmatch/logic/CResource.h b/Server/mods/deathmatch/logic/CResource.h index aaa2fda60d0..eeb05f5c67a 100644 --- a/Server/mods/deathmatch/logic/CResource.h +++ b/Server/mods/deathmatch/logic/CResource.h @@ -347,7 +347,10 @@ class CResource : public EHS void RefreshAutoPermissions(CXMLNode* pNodeAclRequest); void CommitAclRequest(const SAclRequest& request); - bool FindAclRequest(SAclRequest& request); + bool FindAclRequest(SAclRequest& result); + + std::string CalculateACLRequestFingerprint(); + bool HasACLRequestsChanged(); private: bool CheckState(); // if the resource has no Dependents, stop it, if it has, start it. returns true if the resource is started. @@ -450,6 +453,7 @@ class CResource : public EHS SString m_strMinServerReason; CChecksum m_metaChecksum; // Checksum of meta.xml last time this was loaded, generated in GenerateChecksums() + std::string m_strACLRequestFingerprint; uint m_uiFunctionRightCacheRevision = 0; CFastHashMap m_FunctionRightCacheMap; diff --git a/Server/mods/deathmatch/logic/CResourceManager.cpp b/Server/mods/deathmatch/logic/CResourceManager.cpp index 9ba9cdc41f0..5abae7bc84a 100644 --- a/Server/mods/deathmatch/logic/CResourceManager.cpp +++ b/Server/mods/deathmatch/logic/CResourceManager.cpp @@ -184,6 +184,14 @@ bool CResourceManager::Refresh(bool bRefreshAll, const SString strJustThisResour // Add the resource Load(!info.bIsDir, info.strAbsPath, info.strName); } + else if (pResource && pResource->HasResourceChanged()) + { + if (g_pServerInterface->IsRequestingExit()) + return false; + + // Resource exists but has changed, reload it + Load(!info.bIsDir, info.strAbsPath, info.strName); + } } }