From 71b8a61c9777e54e8c210ec4b9e27e1361069e7f Mon Sep 17 00:00:00 2001 From: Tixx <83774803+WiserTixx@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:22:28 +0100 Subject: [PATCH 1/2] Add custom IP bind option --- include/Settings.h | 1 + src/Settings.cpp | 2 ++ src/TConfig.cpp | 5 +++++ src/TNetwork.cpp | 30 ++++++++++++++++++++++-------- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/include/Settings.h b/include/Settings.h index 016bef14..f0c1a2c7 100644 --- a/include/Settings.h +++ b/include/Settings.h @@ -79,6 +79,7 @@ struct Settings { General_Map, General_AuthKey, General_Private, + General_IP, General_Port, General_MaxCars, General_LogChat, diff --git a/src/Settings.cpp b/src/Settings.cpp index a8dfdb84..bb3c5754 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -28,6 +28,7 @@ Settings::Settings() { { General_Map, std::string("/levels/gridmap_v2/info.json") }, { General_AuthKey, std::string("") }, { General_Private, true }, + { General_IP, "::"}, { General_Port, 30814 }, { General_MaxCars, 1 }, { General_LogChat, true }, @@ -47,6 +48,7 @@ Settings::Settings() { { { "General", "Map" }, { General_Map, READ_WRITE } }, { { "General", "AuthKey" }, { General_AuthKey, NO_ACCESS } }, { { "General", "Private" }, { General_Private, READ_ONLY } }, + { { "General", "IP" }, { General_IP, READ_ONLY } }, { { "General", "Port" }, { General_Port, READ_ONLY } }, { { "General", "MaxCars" }, { General_MaxCars, READ_WRITE } }, { { "General", "LogChat" }, { General_LogChat, READ_ONLY } }, diff --git a/src/TConfig.cpp b/src/TConfig.cpp index 0c902a86..39b093b9 100644 --- a/src/TConfig.cpp +++ b/src/TConfig.cpp @@ -34,6 +34,8 @@ static constexpr std::string_view StrDebug = "Debug"; static constexpr std::string_view EnvStrDebug = "BEAMMP_DEBUG"; static constexpr std::string_view StrPrivate = "Private"; static constexpr std::string_view EnvStrPrivate = "BEAMMP_PRIVATE"; +static constexpr std::string_view StrIP = "IP"; +static constexpr std::string_view EnvStrIP = "BEAMMP_IP"; static constexpr std::string_view StrPort = "Port"; static constexpr std::string_view EnvStrPort = "BEAMMP_PORT"; static constexpr std::string_view StrMaxCars = "MaxCars"; @@ -138,6 +140,8 @@ void TConfig::FlushToFile() { data["General"][StrInformationPacket.data()] = Application::Settings.getAsBool(Settings::Key::General_InformationPacket); data["General"][StrAllowGuests.data()] = Application::Settings.getAsBool(Settings::Key::General_AllowGuests); SetComment(data["General"][StrAllowGuests.data()].comments(), " Whether to allow guests"); + data["General"][StrIP.data()] = Application::Settings.getAsString(Settings::Key::General_IP); + SetComment(data["General"][StrIP.data()].comments(), " The IP address to bind the server to, this is NOT related to your public IP."); data["General"][StrPort.data()] = Application::Settings.getAsInt(Settings::Key::General_Port); data["General"][StrName.data()] = Application::Settings.getAsString(Settings::Key::General_Name); SetComment(data["General"][StrTags.data()].comments(), " Add custom identifying tags to your server to make it easier to find. Format should be TagA,TagB,TagC. Note the comma seperation."); @@ -254,6 +258,7 @@ void TConfig::ParseFromFile(std::string_view name) { } else { TryReadValue(data, "General", StrPort, EnvStrPort, Settings::Key::General_Port); } + TryReadValue(data, "General", StrIP, EnvStrIP, Settings::Key::General_IP); TryReadValue(data, "General", StrMaxCars, EnvStrMaxCars, Settings::Key::General_MaxCars); TryReadValue(data, "General", StrMaxPlayers, EnvStrMaxPlayers, Settings::Key::General_MaxPlayers); TryReadValue(data, "General", StrMap, EnvStrMap, Settings::Key::General_Map); diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index 3a40543f..83c1dc98 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -85,9 +85,17 @@ TNetwork::TNetwork(TServer& Server, TPPSMonitor& PPSMonitor, TResourceManager& R void TNetwork::UDPServerMain() { RegisterThread("UDPServer"); - // listen on all ipv6 addresses - ip::udp::endpoint UdpListenEndpoint(ip::make_address("::"), Application::Settings.getAsInt(Settings::Key::General_Port)); + boost::system::error_code ec; + auto address = ip::make_address(Application::Settings.getAsString(Settings::Key::General_IP), ec); + + if (ec) { + beammp_errorf("Failed to parse IP: {}", ec.message()); + Application::GracefullyShutdown(); + } + + ip::udp::endpoint UdpListenEndpoint(address, Application::Settings.getAsInt(Settings::Key::General_Port)); + mUDPSock.open(UdpListenEndpoint.protocol(), ec); if (ec) { beammp_error("open() failed: " + ec.message()); @@ -107,7 +115,7 @@ void TNetwork::UDPServerMain() { Application::GracefullyShutdown(); } Application::SetSubsystemStatus("UDPNetwork", Application::Status::Good); - beammp_info(("Vehicle data network online on port ") + std::to_string(Application::Settings.getAsInt(Settings::Key::General_Port)) + (" with a Max of ") + beammp_info(("Vehicle data network online on port ") + std::to_string(UdpListenEndpoint.port()) + (" with a Max of ") + std::to_string(Application::Settings.getAsInt(Settings::Key::General_MaxPlayers)) + (" Clients")); while (!Application::IsShuttingDown()) { try { @@ -170,12 +178,17 @@ void TNetwork::UDPServerMain() { void TNetwork::TCPServerMain() { RegisterThread("TCPServer"); - // listen on all ipv6 addresses - auto port = uint16_t(Application::Settings.getAsInt(Settings::Key::General_Port)); - ip::tcp::endpoint ListenEp(ip::make_address("::"), port); - beammp_infof("Listening on 0.0.0.0:{0} and [::]:{0}", port); - ip::tcp::socket Listener(mServer.IoCtx()); boost::system::error_code ec; + auto address = ip::make_address(Application::Settings.getAsString(Settings::Key::General_IP), ec); + if (ec) { + beammp_errorf("Failed to parse IP: {}", ec.message()); + return; + } + + ip::tcp::endpoint ListenEp(address, + uint16_t(Application::Settings.getAsInt(Settings::Key::General_Port))); + + ip::tcp::socket Listener(mServer.IoCtx()); Listener.open(ListenEp.protocol(), ec); if (ec) { beammp_errorf("Failed to open socket: {}", ec.message()); @@ -209,6 +222,7 @@ void TNetwork::TCPServerMain() { Application::GracefullyShutdown(); } Application::SetSubsystemStatus("TCPNetwork", Application::Status::Good); + beammp_infof("Listening on {0} port {1}", ListenEp.address().to_string(), (int)ListenEp.port()); beammp_info("Vehicle event network online"); do { try { From 093310c12453118129bffc0c9adfcd3961f40a3f Mon Sep 17 00:00:00 2001 From: Tixx <83774803+WiserTixx@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:36:13 +0100 Subject: [PATCH 2/2] Update IP config comment --- src/TConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TConfig.cpp b/src/TConfig.cpp index 39b093b9..9fa21b41 100644 --- a/src/TConfig.cpp +++ b/src/TConfig.cpp @@ -141,7 +141,7 @@ void TConfig::FlushToFile() { data["General"][StrAllowGuests.data()] = Application::Settings.getAsBool(Settings::Key::General_AllowGuests); SetComment(data["General"][StrAllowGuests.data()].comments(), " Whether to allow guests"); data["General"][StrIP.data()] = Application::Settings.getAsString(Settings::Key::General_IP); - SetComment(data["General"][StrIP.data()].comments(), " The IP address to bind the server to, this is NOT related to your public IP."); + SetComment(data["General"][StrIP.data()].comments(), " The IP address to bind the server to, this is NOT related to your public IP. Can be used if your machine has multiple network interfaces"); data["General"][StrPort.data()] = Application::Settings.getAsInt(Settings::Key::General_Port); data["General"][StrName.data()] = Application::Settings.getAsString(Settings::Key::General_Name); SetComment(data["General"][StrTags.data()].comments(), " Add custom identifying tags to your server to make it easier to find. Format should be TagA,TagB,TagC. Note the comma seperation.");