Skip to content

Commit b24ff88

Browse files
Add new mtaserver.conf rules for server browser/list (PR #3761)
1 parent 8117ebc commit b24ff88

File tree

7 files changed

+211
-60
lines changed

7 files changed

+211
-60
lines changed

Server/mods/deathmatch/editor.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
44
and on Game-Monitor. It is a required parameter. -->
55
<servername>Map Editor Server</servername>
6+
7+
<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
8+
A brief description of the server. -->
9+
<rule name="description" value="" />
10+
11+
<!-- A comma separated list of languages that the server supports (e.g. en). -->
12+
<rule name="languages" value="" />
13+
14+
<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
15+
<rule name="tags" value="" />
16+
17+
<!-- The URL of the server's website. -->
18+
<rule name="website_url" value="" />
19+
20+
<!-- A social media URL #1 (e.g. Discord). -->
21+
<rule name="social_url_1" value="" />
22+
23+
<!-- A social media URL #2 (e.g. YouTube). -->
24+
<rule name="social_url_2" value="" />
25+
26+
<!-- A social media URL #3 (e.g. Facebook). -->
27+
<rule name="social_url_3" value="" />
628

729
<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
830
The email addresses will not be publicly available, and only used by MTA administrators

Server/mods/deathmatch/local.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
44
and on Game-Monitor. It is a required parameter. -->
55
<servername>Default MTA Server</servername>
6+
7+
<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
8+
A brief description of the server. -->
9+
<rule name="description" value="" />
10+
11+
<!-- A comma separated list of languages that the server supports (e.g. en). -->
12+
<rule name="languages" value="" />
13+
14+
<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
15+
<rule name="tags" value="" />
16+
17+
<!-- The URL of the server's website. -->
18+
<rule name="website_url" value="" />
19+
20+
<!-- A social media URL #1 (e.g. Discord). -->
21+
<rule name="social_url_1" value="" />
22+
23+
<!-- A social media URL #2 (e.g. YouTube). -->
24+
<rule name="social_url_2" value="" />
25+
26+
<!-- A social media URL #3 (e.g. Facebook). -->
27+
<rule name="social_url_3" value="" />
628

729
<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
830
The email addresses will not be publicly available, and only used by MTA administrators

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,10 +979,15 @@ bool CGame::Start(int iArgumentCount, char* szArguments[])
979979
}
980980
}
981981

982-
// If ASE is enabled
982+
// Init ASE
983983
m_pASE = new ASE(m_pMainConfig, m_pPlayerManager, static_cast<int>(usServerPort), strServerIPList);
984984
if (m_pMainConfig->GetSerialVerificationEnabled())
985985
m_pASE->SetRuleValue("SerialVerification", "yes");
986+
987+
// Set the Rules loaded from config
988+
for (const auto& [key, value] : m_pMainConfig->GetRulesForASE())
989+
m_pASE->SetRuleValue(key, value);
990+
986991
ApplyAseSetting();
987992
m_pMasterServerAnnouncer = new CMasterServerAnnouncer();
988993
m_pMasterServerAnnouncer->Pulse();

Server/mods/deathmatch/logic/CMainConfig.cpp

Lines changed: 114 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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

898954
bool CMainConfig::IsValidPassword(const char* szPassword)

Server/mods/deathmatch/logic/CMainConfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class CMainConfig : public CXMLConfig
8787
unsigned int GetScriptDebugLogLevel() { return m_uiScriptDebugLogLevel; };
8888
const std::string& GetAccessControlListFile() { return m_strAccessControlListFile; };
8989
bool GetSerialVerificationEnabled() { return m_bVerifySerials; };
90+
const std::map<SString, SString>& GetRulesForASE() const noexcept { return m_RulesForASEMap; };
9091
bool IsDisableAC(const char* szTagAC) { return MapContains(m_DisableComboACMap, szTagAC); };
9192
bool IsEnableDiagnostic(const char* szTag) { return MapContains(m_EnableDiagnosticMap, szTag); };
9293
CMtaVersion GetMinClientVersion() { return m_strMinClientVersion; }
@@ -193,6 +194,7 @@ class CMainConfig : public CXMLConfig
193194
unsigned short m_usFPSLimit;
194195
int m_bDontBroadcastLan;
195196
std::set<SString> m_DisableComboACMap;
197+
std::map<SString, SString> m_RulesForASEMap;
196198
std::set<SString> m_EnableDiagnosticMap;
197199
std::vector<SString> m_AuthSerialGroupList;
198200
bool m_bAuthSerialHttpEnabled;

Server/mods/deathmatch/mtaserver.conf

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,29 @@
33
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
44
and on Game-Monitor. It is a required parameter. -->
55
<servername>Default MTA Server</servername>
6-
6+
7+
<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
8+
A brief description of the server. -->
9+
<rule name="description" value="" />
10+
11+
<!-- A comma separated list of languages that the server supports (e.g. en). -->
12+
<rule name="languages" value="" />
13+
14+
<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
15+
<rule name="tags" value="" />
16+
17+
<!-- The URL of the server's website. -->
18+
<rule name="website_url" value="" />
19+
20+
<!-- A social media URL #1 (e.g. Discord). -->
21+
<rule name="social_url_1" value="" />
22+
23+
<!-- A social media URL #2 (e.g. YouTube). -->
24+
<rule name="social_url_2" value="" />
25+
26+
<!-- A social media URL #3 (e.g. Facebook). -->
27+
<rule name="social_url_3" value="" />
28+
729
<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
830
The email addresses will not be publicly available, and only used by MTA administrators
931
to contact the server owner.

Server/mods/deathmatch/mtaserver.conf.template

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@
44
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
55
and on Game-Monitor. It is a required parameter. -->
66
<servername>Default MTA Server</servername>
7+
8+
<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
9+
A brief description of the server. -->
10+
<rule name="description" value="" />
11+
12+
<!-- A comma separated list of languages that the server supports (e.g. en). -->
13+
<rule name="languages" value="" />
14+
15+
<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
16+
<rule name="tags" value="" />
17+
18+
<!-- The URL of the server's website. -->
19+
<rule name="website_url" value="" />
20+
21+
<!-- A social media URL #1 (e.g. Discord). -->
22+
<rule name="social_url_1" value="" />
23+
24+
<!-- A social media URL #2 (e.g. YouTube). -->
25+
<rule name="social_url_2" value="" />
26+
27+
<!-- A social media URL #3 (e.g. Facebook). -->
28+
<rule name="social_url_3" value="" />
729

830
<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
931
The email addresses will not be publicly available, and only used by MTA administrators

0 commit comments

Comments
 (0)