Skip to content

Commit

Permalink
Add new mtaserver.conf rules for server browser/list (PR #3761)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernando-A-Rocha authored Jan 2, 2025
1 parent 8117ebc commit b24ff88
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 60 deletions.
22 changes: 22 additions & 0 deletions Server/mods/deathmatch/editor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
and on Game-Monitor. It is a required parameter. -->
<servername>Map Editor Server</servername>

<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
A brief description of the server. -->
<rule name="description" value="" />

<!-- A comma separated list of languages that the server supports (e.g. en). -->
<rule name="languages" value="" />

<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
<rule name="tags" value="" />

<!-- The URL of the server's website. -->
<rule name="website_url" value="" />

<!-- A social media URL #1 (e.g. Discord). -->
<rule name="social_url_1" value="" />

<!-- A social media URL #2 (e.g. YouTube). -->
<rule name="social_url_2" value="" />

<!-- A social media URL #3 (e.g. Facebook). -->
<rule name="social_url_3" value="" />

<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
The email addresses will not be publicly available, and only used by MTA administrators
Expand Down
22 changes: 22 additions & 0 deletions Server/mods/deathmatch/local.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
and on Game-Monitor. It is a required parameter. -->
<servername>Default MTA Server</servername>

<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
A brief description of the server. -->
<rule name="description" value="" />

<!-- A comma separated list of languages that the server supports (e.g. en). -->
<rule name="languages" value="" />

<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
<rule name="tags" value="" />

<!-- The URL of the server's website. -->
<rule name="website_url" value="" />

<!-- A social media URL #1 (e.g. Discord). -->
<rule name="social_url_1" value="" />

<!-- A social media URL #2 (e.g. YouTube). -->
<rule name="social_url_2" value="" />

<!-- A social media URL #3 (e.g. Facebook). -->
<rule name="social_url_3" value="" />

<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
The email addresses will not be publicly available, and only used by MTA administrators
Expand Down
7 changes: 6 additions & 1 deletion Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -979,10 +979,15 @@ bool CGame::Start(int iArgumentCount, char* szArguments[])
}
}

// If ASE is enabled
// Init ASE
m_pASE = new ASE(m_pMainConfig, m_pPlayerManager, static_cast<int>(usServerPort), strServerIPList);
if (m_pMainConfig->GetSerialVerificationEnabled())
m_pASE->SetRuleValue("SerialVerification", "yes");

// Set the Rules loaded from config
for (const auto& [key, value] : m_pMainConfig->GetRulesForASE())
m_pASE->SetRuleValue(key, value);

ApplyAseSetting();
m_pMasterServerAnnouncer = new CMasterServerAnnouncer();
m_pMasterServerAnnouncer->Pulse();
Expand Down
172 changes: 114 additions & 58 deletions Server/mods/deathmatch/logic/CMainConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ bool CMainConfig::Load()
return false;
}

// Grab rules
CXMLNode* currentNode = nullptr;
std::size_t currentIndex = 0;
while (currentNode = m_pRootNode->FindSubNode("rule", currentIndex++))
{
CXMLAttribute* attribute = currentNode->GetAttributes().Find("name");
SString ruleName = attribute ? attribute->GetValue() : SString{};

attribute = currentNode->GetAttributes().Find("value");
SString ruleValue = attribute ? attribute->GetValue() : SString{};

if (!ruleName.empty() && !ruleValue.empty())
m_RulesForASEMap[std::move(ruleName)] = std::move(ruleValue);
}

// Strip spaces from beginning and end of server name
m_strServerName = SString(m_strServerName).TrimStart(" ").TrimEnd(" ");

Expand Down Expand Up @@ -237,43 +252,37 @@ bool CMainConfig::Load()
GetInteger(m_pRootNode, "verifyclientsettings", m_iEnableClientChecks);

// Handle the <client_file> nodes
CXMLNode* pNode = NULL;
unsigned int uiCurrentIndex = 0;
do
{
// Grab the current script node
pNode = m_pRootNode->FindSubNode("client_file", uiCurrentIndex++);
if (pNode)
currentNode = nullptr;
currentIndex = 0;
while (currentNode = m_pRootNode->FindSubNode("client_file", currentIndex++))
{
// Grab its "name" attribute
CXMLAttribute* attribute = currentNode->GetAttributes().Find("name");
SString name = attribute ? attribute->GetValue() : SString{};
name = name.Replace("\\", "/").ToLower();

// Grab its "verify" attribute
attribute = currentNode->GetAttributes().Find("verify");
SString verify = attribute ? attribute->GetValue() : SString{};
bool shouldVerify = verify == "true" || verify == "yes" || verify == "1";

// Find bitnumber
bool found = false;
for (std::size_t i = 0; i < std::size(gtaDataFiles); i++)
{
// Grab its "name" attribute
CXMLAttribute* pAttribute = pNode->GetAttributes().Find("name");
SString strName = pAttribute ? pAttribute->GetValue() : "";
strName = strName.Replace("\\", "/").ToLower();

// Grab its "verify" attribute
pAttribute = pNode->GetAttributes().Find("verify");
SString strVerify = pAttribute ? pAttribute->GetValue() : "";
bool bVerify = strVerify == "true" || strVerify == "yes" || strVerify == "1";

// Find bitnumber
bool bFound = false;
for (uint i = 0; i < NUMELMS(gtaDataFiles); i++)
if (name == gtaDataFiles[i].szRealFilename)
{
if (strName == gtaDataFiles[i].szRealFilename)
{
if (bVerify)
m_iEnableClientChecks |= 1 << gtaDataFiles[i].iBitNumber;
else
m_iEnableClientChecks &= ~(1 << gtaDataFiles[i].iBitNumber);
bFound = true;
break;
}
if (shouldVerify)
m_iEnableClientChecks |= 1 << gtaDataFiles[i].iBitNumber;
else
m_iEnableClientChecks &= ~(1 << gtaDataFiles[i].iBitNumber);
found = true;
break;
}

if (!bFound)
CLogger::ErrorPrintf("Unknown client_file '%s'\n", *strName);
}
} while (pNode);
if (!found)
CLogger::ErrorPrintf("Unknown client_file '%s'\n", *name);
}

// allow_gta3_img_mods
SString strImgMods;
Expand Down Expand Up @@ -855,44 +864,91 @@ bool CMainConfig::AddMissingSettings()
if (!g_pGame->IsUsingMtaServerConf())
return false;

SString strTemplateFilename = PathJoin(g_pServerInterface->GetServerModPath(), "mtaserver.conf.template");
const SString templateFileName = PathJoin(g_pServerInterface->GetServerModPath(), "mtaserver.conf.template");

if (!FileExists(strTemplateFilename))
if (!FileExists(templateFileName))
return false;

CXMLFile* pFileTemplate = g_pServerInterface->GetXML()->CreateXML(strTemplateFilename);
CXMLNode* pRootNodeTemplate = pFileTemplate && pFileTemplate->Parse() ? pFileTemplate->GetRootNode() : nullptr;
if (!pRootNodeTemplate)
CXMLFile* templateFile = g_pServerInterface->GetXML()->CreateXML(templateFileName);
CXMLNode* templateRootNode = templateFile && templateFile->Parse() ? templateFile->GetRootNode() : nullptr;
if (!templateRootNode)
{
CLogger::ErrorPrintf("Can't parse '%s'\n", *strTemplateFilename);
CLogger::ErrorPrintf("Can't parse '%s'\n", *templateFileName);
return false;
}

// Check that each item in the template also exists in the server config
bool bChanged = false;
CXMLNode* pPrevNode = nullptr;
for (auto it = pRootNodeTemplate->ChildrenBegin(); it != pRootNodeTemplate->ChildrenEnd(); ++it)
{
CXMLNode* pNodeTemplate = *it;
SString strNodeName = pNodeTemplate->GetTagName();
CXMLNode* pNode = m_pRootNode->FindSubNode(strNodeName);
if (!pNode)
bool hasConfigChanged = false;
CXMLNode* previousNode = nullptr;
for (auto it = templateRootNode->ChildrenBegin(); it != templateRootNode->ChildrenEnd(); ++it)
{
CXMLNode* templateNode = *it;
SString templateNodeTagName = templateNode->GetTagName();

// Find node with exact same attributes
CXMLAttributes& templateAttributes = templateNode->GetAttributes();
CXMLNode* foundNode = nullptr;
for (auto it2 = m_pRootNode->ChildrenBegin(); it2 != m_pRootNode->ChildrenEnd(); ++it2)
{
CXMLNode* tempNode = *it2;
if (tempNode->GetTagName() != templateNodeTagName)
{
continue;
}
CXMLAttributes& attributes = tempNode->GetAttributes();
bool attributesMatch = true;

for (auto it3 = templateAttributes.ListBegin(); it3 != templateAttributes.ListEnd(); ++it3)
{
CXMLAttribute* templateAttribute = *it3;
const SString& strKey = templateAttribute->GetName();
const SString& strValue = templateAttribute->GetValue();

CXMLAttribute* foundAttribute = attributes.Find(strKey);
if (!foundAttribute || foundAttribute->GetValue() != strValue)
{
attributesMatch = false;
break;
}
}

if (attributesMatch)
{
foundNode = tempNode;
break;
}
}
// Create missing node if not found
if (!foundNode)
{
CLogger::LogPrintf("Adding missing '%s' to mtaserver.conf\n", *strNodeName);
SString strNodeValue = pNodeTemplate->GetTagContent();
SString strNodeComment = pNodeTemplate->GetCommentText();
pNode = m_pRootNode->CreateSubNode(strNodeName, pPrevNode);
pNode->SetTagContent(strNodeValue);
pNode->SetCommentText(strNodeComment, true);
bChanged = true;
CLogger::LogPrintf("Adding missing '%s' to mtaserver.conf\n", *templateNodeTagName);
SString value = templateNode->GetTagContent();
SString commentText = templateNode->GetCommentText();
foundNode = m_pRootNode->CreateSubNode(templateNodeTagName, previousNode);
foundNode->SetTagContent(value);
foundNode->SetCommentText(commentText, true);

// Copy attributes from template node
CXMLAttributes& templateAttributes = templateNode->GetAttributes();
for (auto it = templateAttributes.ListBegin(); it != templateAttributes.ListEnd(); ++it)
{
CXMLAttribute* templateAttribute = *it;
const SString& attributeName = templateAttribute->GetName();
const SString& attributeValue = templateAttribute->GetValue();

CXMLAttribute* newAttribute = foundNode->GetAttributes().Create(attributeName);
if (newAttribute)
newAttribute->SetValue(attributeValue);
}
hasConfigChanged = true;
}
pPrevNode = pNode;
previousNode = foundNode;
}

// Clean up
g_pServerInterface->GetXML()->DeleteXML(pFileTemplate);
FileDelete(strTemplateFilename);
return bChanged;
g_pServerInterface->GetXML()->DeleteXML(templateFile);
FileDelete(templateFileName);
return hasConfigChanged;
}

bool CMainConfig::IsValidPassword(const char* szPassword)
Expand Down
2 changes: 2 additions & 0 deletions Server/mods/deathmatch/logic/CMainConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class CMainConfig : public CXMLConfig
unsigned int GetScriptDebugLogLevel() { return m_uiScriptDebugLogLevel; };
const std::string& GetAccessControlListFile() { return m_strAccessControlListFile; };
bool GetSerialVerificationEnabled() { return m_bVerifySerials; };
const std::map<SString, SString>& GetRulesForASE() const noexcept { return m_RulesForASEMap; };
bool IsDisableAC(const char* szTagAC) { return MapContains(m_DisableComboACMap, szTagAC); };
bool IsEnableDiagnostic(const char* szTag) { return MapContains(m_EnableDiagnosticMap, szTag); };
CMtaVersion GetMinClientVersion() { return m_strMinClientVersion; }
Expand Down Expand Up @@ -193,6 +194,7 @@ class CMainConfig : public CXMLConfig
unsigned short m_usFPSLimit;
int m_bDontBroadcastLan;
std::set<SString> m_DisableComboACMap;
std::map<SString, SString> m_RulesForASEMap;
std::set<SString> m_EnableDiagnosticMap;
std::vector<SString> m_AuthSerialGroupList;
bool m_bAuthSerialHttpEnabled;
Expand Down
24 changes: 23 additions & 1 deletion Server/mods/deathmatch/mtaserver.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,29 @@
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
and on Game-Monitor. It is a required parameter. -->
<servername>Default MTA Server</servername>


<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
A brief description of the server. -->
<rule name="description" value="" />

<!-- A comma separated list of languages that the server supports (e.g. en). -->
<rule name="languages" value="" />

<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
<rule name="tags" value="" />

<!-- The URL of the server's website. -->
<rule name="website_url" value="" />

<!-- A social media URL #1 (e.g. Discord). -->
<rule name="social_url_1" value="" />

<!-- A social media URL #2 (e.g. YouTube). -->
<rule name="social_url_2" value="" />

<!-- A social media URL #3 (e.g. Facebook). -->
<rule name="social_url_3" value="" />

<!-- This parameter specifies the contact email addresses for the owner(s) of this server.
The email addresses will not be publicly available, and only used by MTA administrators
to contact the server owner.
Expand Down
22 changes: 22 additions & 0 deletions Server/mods/deathmatch/mtaserver.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@
<!-- This parameter specifies the name the server will be visible as in the ingame server browser
and on Game-Monitor. It is a required parameter. -->
<servername>Default MTA Server</servername>

<!-- The rule parameters are optional settings that the server will make public for the server browser/list.
A brief description of the server. -->
<rule name="description" value="" />

<!-- A comma separated list of languages that the server supports (e.g. en). -->
<rule name="languages" value="" />

<!-- A comma separated list of tags that describe the server (e.g. freeroam,roleplay). -->
<rule name="tags" value="" />

<!-- The URL of the server's website. -->
<rule name="website_url" value="" />

<!-- A social media URL #1 (e.g. Discord). -->
<rule name="social_url_1" value="" />

<!-- A social media URL #2 (e.g. YouTube). -->
<rule name="social_url_2" value="" />

<!-- A social media URL #3 (e.g. Facebook). -->
<rule name="social_url_3" value="" />

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

0 comments on commit b24ff88

Please sign in to comment.