From e9a2ffde3864551ee5cd60613f27f70f33f194aa Mon Sep 17 00:00:00 2001 From: furo Date: Fri, 6 Sep 2024 16:32:56 +0200 Subject: [PATCH] Add `verify_url` field to master for automatic verification --- src/engine/client/client.cpp | 12 ++++++++++++ src/engine/server/server.cpp | 4 ++++ src/engine/serverbrowser.h | 1 + src/engine/shared/config_variables.h | 1 + src/engine/shared/serverinfo.cpp | 7 +++++++ src/engine/shared/serverinfo.h | 1 + 6 files changed, 26 insertions(+) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 8f416bc97..5c67958e0 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -621,6 +621,18 @@ void CClient::Connect(const char *pAddress, const char *pPassword) else m_aNetClient[CONN_MAIN].Connect(aConnectAddrs, NumConnectAddrs); + const CServerBrowser::CServerEntry *pEntry = m_ServerBrowser.Find(aConnectAddrs[0]); + if(pEntry != nullptr && pEntry->m_GotInfo) + { + if(str_length(pEntry->m_Info.m_aVerifyUrl)) + { + std::shared_ptr pVerifyGet = HttpGet(pEntry->m_Info.m_aVerifyUrl); + pVerifyGet->Timeout(CTimeout{10000, 0, 500, 10}); + pVerifyGet->IpResolve(aConnectAddrs[0].type == NETTYPE_IPV4 ? IPRESOLVE::V4 : IPRESOLVE::V6); + Http()->Run(pVerifyGet); + } + } + m_aNetClient[CONN_MAIN].RefreshStun(); SetState(IClient::STATE_CONNECTING); diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 65aaf57e7..004a33c46 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -2357,6 +2357,10 @@ void CServer::UpdateRegisterServerInfo() JsonWriter.WriteAttribute("requires_login"); JsonWriter.WriteBoolValue(false); + // Client will send a HTTP GET request to the url of sv_verify_url upon connecting + JsonWriter.WriteAttribute("verify_url"); + JsonWriter.WriteStrValue(g_Config.m_SvVerifyUrl); + JsonWriter.WriteAttribute("clients"); JsonWriter.BeginArray(); diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index c788fccc2..08e749b42 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -118,6 +118,7 @@ public: CClient m_aClients[SERVERINFO_MAX_CLIENTS]; int m_NumFilteredPlayers; bool m_RequiresLogin; + char m_aVerifyUrl[128]; static int EstimateLatency(int Loc1, int Loc2); static bool ParseLocation(int *pResult, const char *pString); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 02849f17c..f4ae09315 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -444,6 +444,7 @@ MACRO_CONFIG_INT(SvDnsblBan, sv_dnsbl_ban, 0, 0, 1, CFGFLAG_SERVER, "Automatical MACRO_CONFIG_STR(SvDnsblBanReason, sv_dnsbl_ban_reason, 128, "VPN detected, try connecting without. Contact admin if mistaken", CFGFLAG_SERVER, "Ban reason for 'sv_dnsbl_ban'") MACRO_CONFIG_INT(SvDnsblChat, sv_dnsbl_chat, 0, 0, 1, CFGFLAG_SERVER, "Don't allow chat from blacklisted addresses") MACRO_CONFIG_INT(SvRconVote, sv_rcon_vote, 0, 0, 1, CFGFLAG_SERVER, "Only allow authed clients to call votes") +MACRO_CONFIG_STR(SvVerifyUrl, sv_verify_url, 128, "", CFGFLAG_SERVER, "A URL which the client will send a HTTP GET request to upon connecting") MACRO_CONFIG_INT(SvPlayerDemoRecord, sv_player_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos for each player") MACRO_CONFIG_INT(SvDemoChat, sv_demo_chat, 0, 0, 1, CFGFLAG_SERVER, "Record chat for demos") diff --git a/src/engine/shared/serverinfo.cpp b/src/engine/shared/serverinfo.cpp index 3e6ef8e57..72183ad9f 100644 --- a/src/engine/shared/serverinfo.cpp +++ b/src/engine/shared/serverinfo.cpp @@ -72,6 +72,7 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson) const json_value &Version = ServerInfo["version"]; const json_value &Clients = ServerInfo["clients"]; const json_value &RequiresLogin = ServerInfo["requires_login"]; + const json_value &VerifyUrl = ServerInfo["verify_url"]; Error = false; Error = Error || MaxClients.type != json_integer; @@ -103,6 +104,11 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson) { pOut->m_RequiresLogin = RequiresLogin; } + str_copy(pOut->m_aVerifyUrl, ""); + if(VerifyUrl.type == json_string) + { + str_copy(pOut->m_aVerifyUrl, VerifyUrl); + } pOut->m_Passworded = Passworded; str_copy(pOut->m_aGameType, GameType); str_copy(pOut->m_aName, Name); @@ -239,6 +245,7 @@ CServerInfo2::operator CServerInfo() const str_copy(Result.m_aName, m_aName); str_copy(Result.m_aMap, m_aMapName); str_copy(Result.m_aVersion, m_aVersion); + str_copy(Result.m_aVerifyUrl, m_aVerifyUrl); for(int i = 0; i < minimum(m_NumClients, (int)SERVERINFO_MAX_CLIENTS); i++) { diff --git a/src/engine/shared/serverinfo.h b/src/engine/shared/serverinfo.h index 4e4c28902..a6ddb47de 100644 --- a/src/engine/shared/serverinfo.h +++ b/src/engine/shared/serverinfo.h @@ -39,6 +39,7 @@ public: char m_aMapName[MAX_MAP_LENGTH]; char m_aVersion[32]; bool m_RequiresLogin; + char m_aVerifyUrl[128]; bool operator==(const CServerInfo2 &Other) const; bool operator!=(const CServerInfo2 &Other) const { return !(*this == Other); }