|
22 | 22 | #include "CHTTPD.h" |
23 | 23 | #include "CStaticFunctionDefinitions.h" |
24 | 24 |
|
25 | | -#define MTA_SERVER_CONF_TEMPLATE "mtaserver.conf.template" |
| 25 | +#define SETTINGS_TEMPLATE_PATH "mtaserver.conf.template" |
26 | 26 |
|
27 | 27 | extern CGame* g_pGame; |
28 | 28 |
|
@@ -864,91 +864,90 @@ bool CMainConfig::AddMissingSettings() |
864 | 864 | if (!g_pGame->IsUsingMtaServerConf()) |
865 | 865 | return false; |
866 | 866 |
|
867 | | - const SString templateFileName = PathJoin(g_pServerInterface->GetServerModPath(), "mtaserver.conf.template"); |
868 | | - |
| 867 | + const std::string templateFileName = PathJoin(g_pServerInterface->GetServerModPath(), SETTINGS_TEMPLATE_PATH); |
869 | 868 | if (!FileExists(templateFileName)) |
870 | 869 | return false; |
871 | 870 |
|
872 | | - CXMLFile* templateFile = g_pServerInterface->GetXML()->CreateXML(templateFileName); |
873 | | - CXMLNode* templateRootNode = templateFile && templateFile->Parse() ? templateFile->GetRootNode() : nullptr; |
| 871 | + std::unique_ptr<CXMLFile> templateFile(g_pServerInterface->GetXML()->CreateXML(templateFileName.c_str())); |
| 872 | + if (!templateFile || !templateFile->Parse()) |
| 873 | + { |
| 874 | + CLogger::ErrorPrintf("Failed to parse template file: '%s'\n", templateFileName.c_str()); |
| 875 | + return false; |
| 876 | + } |
| 877 | + |
| 878 | + CXMLNode* templateRootNode = templateFile->GetRootNode(); |
874 | 879 | if (!templateRootNode) |
875 | 880 | { |
876 | | - CLogger::ErrorPrintf("Can't parse '%s'\n", *templateFileName); |
| 881 | + CLogger::ErrorPrintf("Template file '%s' has no root node\n", templateFileName.c_str()); |
877 | 882 | return false; |
878 | 883 | } |
879 | 884 |
|
880 | 885 | // Check that each item in the template also exists in the server config |
881 | | - bool hasConfigChanged = false; |
| 886 | + bool configChanged = false; |
882 | 887 | CXMLNode* previousNode = nullptr; |
| 888 | + |
883 | 889 | for (auto it = templateRootNode->ChildrenBegin(); it != templateRootNode->ChildrenEnd(); ++it) |
884 | 890 | { |
885 | 891 | CXMLNode* templateNode = *it; |
886 | | - SString templateNodeTagName = templateNode->GetTagName(); |
| 892 | + const std::string& templateNodeName = templateNode->GetTagName(); |
887 | 893 |
|
| 894 | + // Skip certain optional nodes |
| 895 | + if (templateNodeName == "resource" || templateNodeName == "module") |
| 896 | + continue; |
| 897 | + |
888 | 898 | // Find node with exact same attributes |
889 | 899 | CXMLAttributes& templateAttributes = templateNode->GetAttributes(); |
890 | 900 | CXMLNode* foundNode = nullptr; |
891 | 901 | for (auto it2 = m_pRootNode->ChildrenBegin(); it2 != m_pRootNode->ChildrenEnd(); ++it2) |
892 | 902 | { |
893 | 903 | CXMLNode* tempNode = *it2; |
894 | | - if (tempNode->GetTagName() != templateNodeTagName) |
895 | | - { |
| 904 | + if (tempNode->GetTagName() != templateNodeName) |
896 | 905 | continue; |
897 | | - } |
| 906 | + |
898 | 907 | CXMLAttributes& attributes = tempNode->GetAttributes(); |
899 | | - bool attributesMatch = true; |
900 | | - |
| 908 | + bool attributesMatch = true; |
| 909 | + |
901 | 910 | for (auto it3 = templateAttributes.ListBegin(); it3 != templateAttributes.ListEnd(); ++it3) |
902 | 911 | { |
903 | 912 | 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) |
| 913 | + const SString& attrName = templateAttribute->GetName(); |
| 914 | + |
| 915 | + // Don't check value attribute which is intended to be different |
| 916 | + if (attrName == "value") |
| 917 | + continue; |
| 918 | + |
| 919 | + const SString& attrValue = templateAttribute->GetValue(); |
| 920 | + |
| 921 | + CXMLAttribute* foundAttribute = attributes.Find(attrName); |
| 922 | + if (!foundAttribute || foundAttribute->GetValue() != attrValue) |
909 | 923 | { |
910 | 924 | attributesMatch = false; |
911 | 925 | break; |
912 | 926 | } |
913 | 927 | } |
914 | | - |
| 928 | + |
915 | 929 | if (attributesMatch) |
916 | 930 | { |
917 | 931 | foundNode = tempNode; |
918 | 932 | break; |
919 | 933 | } |
920 | 934 | } |
921 | | - // Create missing node if not found |
| 935 | + |
922 | 936 | if (!foundNode) |
923 | 937 | { |
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 | + const std::string templateNodeValue = templateNode->GetTagContent(); |
| 939 | + const SString templateNodeComment = templateNode->GetCommentText(); |
938 | 940 |
|
939 | | - CXMLAttribute* newAttribute = foundNode->GetAttributes().Create(attributeName); |
940 | | - if (newAttribute) |
941 | | - newAttribute->SetValue(attributeValue); |
942 | | - } |
943 | | - hasConfigChanged = true; |
| 941 | + foundNode = m_pRootNode->CreateSubNode(templateNodeName.c_str(), previousNode); |
| 942 | + foundNode->SetTagContent(templateNodeValue.c_str()); |
| 943 | + foundNode->SetCommentText(templateNodeComment.c_str(), true); |
| 944 | + |
| 945 | + CLogger::LogPrintf("Added missing '%s' setting to mtaserver.conf\n", templateNodeName.c_str()); |
| 946 | + configChanged = true; |
944 | 947 | } |
945 | 948 | previousNode = foundNode; |
946 | 949 | } |
947 | | - |
948 | | - // Clean up |
949 | | - g_pServerInterface->GetXML()->DeleteXML(templateFile); |
950 | | - FileDelete(templateFileName); |
951 | | - return hasConfigChanged; |
| 950 | + return configChanged; |
952 | 951 | } |
953 | 952 |
|
954 | 953 | bool CMainConfig::IsValidPassword(const char* szPassword) |
|
0 commit comments