@@ -135,6 +135,21 @@ bool CMainConfig::Load()
135135 return false ;
136136 }
137137
138+ // Grab rules
139+ CXMLNode* currentNode = nullptr ;
140+ std::size_t currentIndex = 0 ;
141+ while (currentNode = m_pRootNode->FindSubNode (" rule" , currentIndex++))
142+ {
143+ CXMLAttribute* attribute = currentNode->GetAttributes ().Find (" name" );
144+ SString ruleName = attribute ? attribute->GetValue () : SString{};
145+
146+ attribute = currentNode->GetAttributes ().Find (" value" );
147+ SString ruleValue = attribute ? attribute->GetValue () : SString{};
148+
149+ if (!ruleName.empty () && !ruleValue.empty ())
150+ m_RulesForASEMap[std::move (ruleName)] = std::move (ruleValue);
151+ }
152+
138153 // Strip spaces from beginning and end of server name
139154 m_strServerName = SString (m_strServerName).TrimStart (" " ).TrimEnd (" " );
140155
@@ -237,43 +252,37 @@ bool CMainConfig::Load()
237252 GetInteger (m_pRootNode, " verifyclientsettings" , m_iEnableClientChecks);
238253
239254 // Handle the <client_file> nodes
240- CXMLNode* pNode = NULL ;
241- unsigned int uiCurrentIndex = 0 ;
242- do
243- {
244- // Grab the current script node
245- pNode = m_pRootNode->FindSubNode (" client_file" , uiCurrentIndex++);
246- if (pNode)
255+ currentNode = nullptr ;
256+ currentIndex = 0 ;
257+ while (currentNode = m_pRootNode->FindSubNode (" client_file" , currentIndex++))
258+ {
259+ // Grab its "name" attribute
260+ CXMLAttribute* attribute = currentNode->GetAttributes ().Find (" name" );
261+ SString name = attribute ? attribute->GetValue () : SString{};
262+ name = name.Replace (" \\ " , " /" ).ToLower ();
263+
264+ // Grab its "verify" attribute
265+ attribute = currentNode->GetAttributes ().Find (" verify" );
266+ SString verify = attribute ? attribute->GetValue () : SString{};
267+ bool shouldVerify = verify == " true" || verify == " yes" || verify == " 1" ;
268+
269+ // Find bitnumber
270+ bool found = false ;
271+ for (std::size_t i = 0 ; i < std::size (gtaDataFiles); i++)
247272 {
248- // Grab its "name" attribute
249- CXMLAttribute* pAttribute = pNode->GetAttributes ().Find (" name" );
250- SString strName = pAttribute ? pAttribute->GetValue () : " " ;
251- strName = strName.Replace (" \\ " , " /" ).ToLower ();
252-
253- // Grab its "verify" attribute
254- pAttribute = pNode->GetAttributes ().Find (" verify" );
255- SString strVerify = pAttribute ? pAttribute->GetValue () : " " ;
256- bool bVerify = strVerify == " true" || strVerify == " yes" || strVerify == " 1" ;
257-
258- // Find bitnumber
259- bool bFound = false ;
260- for (uint i = 0 ; i < NUMELMS (gtaDataFiles); i++)
273+ if (name == gtaDataFiles[i].szRealFilename )
261274 {
262- if (strName == gtaDataFiles[i].szRealFilename )
263- {
264- if (bVerify)
265- m_iEnableClientChecks |= 1 << gtaDataFiles[i].iBitNumber ;
266- else
267- m_iEnableClientChecks &= ~(1 << gtaDataFiles[i].iBitNumber );
268- bFound = true ;
269- break ;
270- }
275+ if (shouldVerify)
276+ m_iEnableClientChecks |= 1 << gtaDataFiles[i].iBitNumber ;
277+ else
278+ m_iEnableClientChecks &= ~(1 << gtaDataFiles[i].iBitNumber );
279+ found = true ;
280+ break ;
271281 }
272-
273- if (!bFound)
274- CLogger::ErrorPrintf (" Unknown client_file '%s'\n " , *strName);
275282 }
276- } while (pNode);
283+ if (!found)
284+ CLogger::ErrorPrintf (" Unknown client_file '%s'\n " , *name);
285+ }
277286
278287 // allow_gta3_img_mods
279288 SString strImgMods;
@@ -855,44 +864,91 @@ bool CMainConfig::AddMissingSettings()
855864 if (!g_pGame->IsUsingMtaServerConf ())
856865 return false ;
857866
858- SString strTemplateFilename = PathJoin (g_pServerInterface->GetServerModPath (), " mtaserver.conf.template" );
867+ const SString templateFileName = PathJoin (g_pServerInterface->GetServerModPath (), " mtaserver.conf.template" );
859868
860- if (!FileExists (strTemplateFilename ))
869+ if (!FileExists (templateFileName ))
861870 return false ;
862871
863- CXMLFile* pFileTemplate = g_pServerInterface->GetXML ()->CreateXML (strTemplateFilename );
864- CXMLNode* pRootNodeTemplate = pFileTemplate && pFileTemplate ->Parse () ? pFileTemplate ->GetRootNode () : nullptr ;
865- if (!pRootNodeTemplate )
872+ CXMLFile* templateFile = g_pServerInterface->GetXML ()->CreateXML (templateFileName );
873+ CXMLNode* templateRootNode = templateFile && templateFile ->Parse () ? templateFile ->GetRootNode () : nullptr ;
874+ if (!templateRootNode )
866875 {
867- CLogger::ErrorPrintf (" Can't parse '%s'\n " , *strTemplateFilename );
876+ CLogger::ErrorPrintf (" Can't parse '%s'\n " , *templateFileName );
868877 return false ;
869878 }
870879
871880 // Check that each item in the template also exists in the server config
872- bool bChanged = false ;
873- CXMLNode* pPrevNode = nullptr ;
874- for (auto it = pRootNodeTemplate->ChildrenBegin (); it != pRootNodeTemplate->ChildrenEnd (); ++it)
875- {
876- CXMLNode* pNodeTemplate = *it;
877- SString strNodeName = pNodeTemplate->GetTagName ();
878- CXMLNode* pNode = m_pRootNode->FindSubNode (strNodeName);
879- if (!pNode)
881+ bool hasConfigChanged = false ;
882+ CXMLNode* previousNode = nullptr ;
883+ for (auto it = templateRootNode->ChildrenBegin (); it != templateRootNode->ChildrenEnd (); ++it)
884+ {
885+ CXMLNode* templateNode = *it;
886+ SString templateNodeTagName = templateNode->GetTagName ();
887+
888+ // Find node with exact same attributes
889+ CXMLAttributes& templateAttributes = templateNode->GetAttributes ();
890+ CXMLNode* foundNode = nullptr ;
891+ for (auto it2 = m_pRootNode->ChildrenBegin (); it2 != m_pRootNode->ChildrenEnd (); ++it2)
892+ {
893+ CXMLNode* tempNode = *it2;
894+ if (tempNode->GetTagName () != templateNodeTagName)
895+ {
896+ continue ;
897+ }
898+ CXMLAttributes& attributes = tempNode->GetAttributes ();
899+ bool attributesMatch = true ;
900+
901+ for (auto it3 = templateAttributes.ListBegin (); it3 != templateAttributes.ListEnd (); ++it3)
902+ {
903+ CXMLAttribute* templateAttribute = *it3;
904+ const SString& strKey = templateAttribute->GetName ();
905+ const SString& strValue = templateAttribute->GetValue ();
906+
907+ CXMLAttribute* foundAttribute = attributes.Find (strKey);
908+ if (!foundAttribute || foundAttribute->GetValue () != strValue)
909+ {
910+ attributesMatch = false ;
911+ break ;
912+ }
913+ }
914+
915+ if (attributesMatch)
916+ {
917+ foundNode = tempNode;
918+ break ;
919+ }
920+ }
921+ // Create missing node if not found
922+ if (!foundNode)
880923 {
881- CLogger::LogPrintf (" Adding missing '%s' to mtaserver.conf\n " , *strNodeName);
882- SString strNodeValue = pNodeTemplate->GetTagContent ();
883- SString strNodeComment = pNodeTemplate->GetCommentText ();
884- pNode = m_pRootNode->CreateSubNode (strNodeName, pPrevNode);
885- pNode->SetTagContent (strNodeValue);
886- pNode->SetCommentText (strNodeComment, true );
887- bChanged = true ;
924+ CLogger::LogPrintf (" Adding missing '%s' to mtaserver.conf\n " , *templateNodeTagName);
925+ SString value = templateNode->GetTagContent ();
926+ SString commentText = templateNode->GetCommentText ();
927+ foundNode = m_pRootNode->CreateSubNode (templateNodeTagName, previousNode);
928+ foundNode->SetTagContent (value);
929+ foundNode->SetCommentText (commentText, true );
930+
931+ // Copy attributes from template node
932+ CXMLAttributes& templateAttributes = templateNode->GetAttributes ();
933+ for (auto it = templateAttributes.ListBegin (); it != templateAttributes.ListEnd (); ++it)
934+ {
935+ CXMLAttribute* templateAttribute = *it;
936+ const SString& attributeName = templateAttribute->GetName ();
937+ const SString& attributeValue = templateAttribute->GetValue ();
938+
939+ CXMLAttribute* newAttribute = foundNode->GetAttributes ().Create (attributeName);
940+ if (newAttribute)
941+ newAttribute->SetValue (attributeValue);
942+ }
943+ hasConfigChanged = true ;
888944 }
889- pPrevNode = pNode ;
945+ previousNode = foundNode ;
890946 }
891947
892948 // Clean up
893- g_pServerInterface->GetXML ()->DeleteXML (pFileTemplate );
894- FileDelete (strTemplateFilename );
895- return bChanged ;
949+ g_pServerInterface->GetXML ()->DeleteXML (templateFile );
950+ FileDelete (templateFileName );
951+ return hasConfigChanged ;
896952}
897953
898954bool CMainConfig::IsValidPassword (const char * szPassword)
0 commit comments