From 0432309e4a0a2f50c8743b21946dba25209bcc9d Mon Sep 17 00:00:00 2001 From: SaltySnail Date: Thu, 25 Jun 2026 18:37:38 +0200 Subject: [PATCH] Remove restricted region --- CMakeLists.txt | 2 ++ include/Common.h | 3 +++ include/RegionHandler.h | 33 +++++++++++++++++++++++++++++++++ src/Common.cpp | 15 ++++++++++----- src/RegionHandler.cpp | 35 +++++++++++++++++++++++++++++++++++ src/TConsole.cpp | 4 ++++ src/THeartbeatThread.cpp | 5 ++++- src/TNetwork.cpp | 4 ++++ 8 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 include/RegionHandler.h create mode 100644 src/RegionHandler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ef728b..d55d0e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ set(PRJ_HEADERS include/ChronoWrapper.h include/TConnectionLimiter.h include/TLuaResult.h + include/RegionHandler.h ) # add all source files (.cpp) to this, except the one with main() set(PRJ_SOURCES @@ -84,6 +85,7 @@ set(PRJ_SOURCES src/ChronoWrapper.cpp src/TConnectionLimiter.cpp src/TLuaResult.cpp + src/RegionHandler.cpp ) find_package(Lua REQUIRED) diff --git a/include/Common.h b/include/Common.h index f835344..291fd66 100644 --- a/include/Common.h +++ b/include/Common.h @@ -86,6 +86,7 @@ public: static std::string GetBackendUrlForAuth(); static std::string GetBackendUrlForSocketIO(); + static void TopLevelDomainFailed(bool failed); static std::string RegionToTopLevelDomain(const std::string region); static void CheckForUpdates(); static std::array VersionStrToInts(const std::string& str); @@ -125,6 +126,8 @@ private: static inline bool mShutdown { false }; static inline std::mutex mShutdownHandlersMutex {}; static inline std::deque mShutdownHandlers {}; + static inline int mTLDIndex { 0 }; + static inline std::vector mValidTLDs {"beammp.com", "beammp.ru"}; static inline Version mVersion { 3, 9, 3 }; }; diff --git a/include/RegionHandler.h b/include/RegionHandler.h new file mode 100644 index 0000000..b82c1d8 --- /dev/null +++ b/include/RegionHandler.h @@ -0,0 +1,33 @@ +// BeamMP, the BeamNG.drive multiplayer mod. +// Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors. +// +// BeamMP Ltd. can be contacted by electronic mail via contact@beammp.com. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include +#include + +class RegionHandler final { +public: + RegionHandler() = delete; + static void TopLevelDomainFailed(bool failed); + static std::string RegionToTopLevelDomain(const std::string region); +private: + static inline unsigned int mRegionIndex { 0 }; + const static inline std::array mValidTLDs {"beammp.com", "beammp.ru"}; +}; diff --git a/src/Common.cpp b/src/Common.cpp index 1816389..4859980 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -94,15 +94,20 @@ std::string Application::GetBackendUrlForSocketIO() return "https://backend." + RegionToTopLevelDomain(Settings.getAsString(Settings::Key::General_Region)); } +void Application::TopLevelDomainFailed(bool failed) +{ + if (failed) { + beammp_info("Top Level Domain (" + mValidTLDs[mTLDIndex % mValidTLDs.size()] + ") failed to respond correctly, switching to " + mValidTLDs[(mTLDIndex + 1) % mValidTLDs.size()]); + mTLDIndex++; + } +} + std::string Application::RegionToTopLevelDomain(const std::string region) { - if (region == "Restricted") { - return "beammp.ru"; - } - else if (region == "Developer") { + if (region == "Developer") { return "beammp.dev"; } - return "beammp.com"; // Global + return mValidTLDs[mTLDIndex % mValidTLDs.size()]; // Global } std::array Application::VersionStrToInts(const std::string& str) { diff --git a/src/RegionHandler.cpp b/src/RegionHandler.cpp new file mode 100644 index 0000000..07a947e --- /dev/null +++ b/src/RegionHandler.cpp @@ -0,0 +1,35 @@ +// BeamMP, the BeamNG.drive multiplayer mod. +// Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors. +// +// BeamMP Ltd. can be contacted by electronic mail via contact@beammp.com. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "RegionHandler.h" +#include "Common.h" + +void RegionHandler::TopLevelDomainFailed(bool failed) +{ + if (!failed) return; + beammp_info("Top level domain of " + mValidTLDs[mRegionIndex % mValidTLDs.size()] + " didn't respond correctly , changing domain to " + mValidTLDs[(mRegionIndex + 1) % mValidTLDs.size()]); + mRegionIndex++; +} + +std::string RegionHandler::RegionToTopLevelDomain(const std::string region) +{ + if (region == "Developer") { + return "beammp.dev"; + } + return mValidTLDs[mRegionIndex % mValidTLDs.size()]; // Global +} diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 2710914..053de22 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -297,6 +297,10 @@ void TConsole::Command_NetTest(const std::string& cmd, const std::vector -#include void THeartbeatThread::operator()() { RegisterThread("Heartbeat"); @@ -63,6 +62,10 @@ void THeartbeatThread::operator()() { bool Ok = false; for (const auto& Url : Application::GetBackendUrlsInOrder()) { T = Http::POST(Url + Target, Body, "application/json", &ResponseCode, { { "api-v", "2" } }); + if (T == Http::ErrorString || ResponseCode != 200) { + Application::TopLevelDomainFailed(true); + T = Http::POST(Url + Target, Body, "application/json", &ResponseCode, { { "api-v", "2" } }); + } if (!Application::Settings.getAsBool(Settings::Key::General_Private)) { beammp_debug("Backend response was: `" + T + "`"); diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index 003c94b..24ec42e 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -440,6 +440,10 @@ std::shared_ptr TNetwork::Authentication(TConnection&& RawConnection) { unsigned int ResponseCode = 0; AuthResStr = Http::POST(Application::GetBackendUrlForAuth() + Target, AuthReq.dump(), "application/json", &ResponseCode); + if (AuthResStr == Http::ErrorString || ResponseCode != 200) { + Application::TopLevelDomainFailed(true); + AuthResStr = Http::POST(Application::GetBackendUrlForAuth() + Target, AuthReq.dump(), "application/json", &ResponseCode); + } } catch (const std::exception& e) { beammp_debugf("Invalid json sent by client, kicking: {}", e.what());