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