From 89db370e12e032207e8618d969139d179608638d Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Mon, 25 Dec 2023 16:16:01 +0100 Subject: [PATCH 1/2] use env variables by default to override config values --- include/TConfig.h | 6 ++-- src/TConfig.cpp | 76 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/include/TConfig.h b/include/TConfig.h index 634fcb8..1a3b62b 100644 --- a/include/TConfig.h +++ b/include/TConfig.h @@ -22,9 +22,9 @@ private: void CreateConfigFile(); void ParseFromFile(std::string_view name); void PrintDebug(); - void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, std::string& OutValue); - void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, bool& OutValue); - void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, int& OutValue); + void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, std::string& OutValue); + void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, bool& OutValue); + void TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, int& OutValue); void ParseOldFormat(); bool IsDefault(); diff --git a/src/TConfig.cpp b/src/TConfig.cpp index 645325b..11d5f79 100644 --- a/src/TConfig.cpp +++ b/src/TConfig.cpp @@ -1,6 +1,7 @@ #include "Common.h" #include "TConfig.h" +#include #include #include #include @@ -8,16 +9,27 @@ // General 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 StrPort = "Port"; +static constexpr std::string_view EnvStrPort = "BEAMMP_PORT"; static constexpr std::string_view StrMaxCars = "MaxCars"; +static constexpr std::string_view EnvStrMaxCars = "BEAMMP_MAX_CARS"; static constexpr std::string_view StrMaxPlayers = "MaxPlayers"; +static constexpr std::string_view EnvStrMaxPlayers = "BEAMMP_MAX_PLAYERS"; static constexpr std::string_view StrMap = "Map"; +static constexpr std::string_view EnvStrMap = "BEAMMP_MAP"; static constexpr std::string_view StrName = "Name"; +static constexpr std::string_view EnvStrName = "BEAMMP_NAME"; static constexpr std::string_view StrDescription = "Description"; +static constexpr std::string_view EnvStrDescription = "BEAMMP_DESCRIPTION"; static constexpr std::string_view StrResourceFolder = "ResourceFolder"; +static constexpr std::string_view EnvStrResourceFolder = "BEAMMP_RESOURCE_FOLDER"; static constexpr std::string_view StrAuthKey = "AuthKey"; +static constexpr std::string_view EnvStrAuthKey = "BEAMMP_AUTH_KEY"; static constexpr std::string_view StrLogChat = "LogChat"; +static constexpr std::string_view EnvStrLogChat = "BEAMMP_LOG_CHAT"; static constexpr std::string_view StrPassword = "Password"; // Misc @@ -159,19 +171,35 @@ void TConfig::CreateConfigFile() { FlushToFile(); } -void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, std::string& OutValue) { +void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, std::string& OutValue) { + if (!Env.empty()) { + if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { + OutValue = std::string(envp); + } + } if (Table[Category.c_str()][Key.data()].is_string()) { OutValue = Table[Category.c_str()][Key.data()].as_string(); } } -void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, bool& OutValue) { +void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, bool& OutValue) { + if (!Env.empty()) { + if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { + auto Str = std::string(envp); + OutValue = Str == "1" || Str == "true"; + } + } if (Table[Category.c_str()][Key.data()].is_boolean()) { OutValue = Table[Category.c_str()][Key.data()].as_boolean(); } } -void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, int& OutValue) { +void TConfig::TryReadValue(toml::value& Table, const std::string& Category, const std::string_view& Key, const std::string_view& Env, int& OutValue) { + if (!Env.empty()) { + if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { + OutValue = int(std::strtol(envp, nullptr, 10)); + } + } if (Table[Category.c_str()][Key.data()].is_integer()) { OutValue = int(Table[Category.c_str()][Key.data()].as_integer()); } @@ -181,29 +209,29 @@ void TConfig::ParseFromFile(std::string_view name) { try { toml::value data = toml::parse(name.data()); // GENERAL - TryReadValue(data, "General", StrDebug, Application::Settings.DebugModeEnabled); - TryReadValue(data, "General", StrPrivate, Application::Settings.Private); - TryReadValue(data, "General", StrPort, Application::Settings.Port); - TryReadValue(data, "General", StrMaxCars, Application::Settings.MaxCars); - TryReadValue(data, "General", StrMaxPlayers, Application::Settings.MaxPlayers); - TryReadValue(data, "General", StrMap, Application::Settings.MapName); - TryReadValue(data, "General", StrName, Application::Settings.ServerName); - TryReadValue(data, "General", StrDescription, Application::Settings.ServerDesc); - TryReadValue(data, "General", StrResourceFolder, Application::Settings.Resource); - TryReadValue(data, "General", StrAuthKey, Application::Settings.Key); - TryReadValue(data, "General", StrLogChat, Application::Settings.LogChat); - TryReadValue(data, "General", StrPassword, Application::Settings.Password); + TryReadValue(data, "General", StrDebug, EnvStrDebug, Application::Settings.DebugModeEnabled); + TryReadValue(data, "General", StrPrivate, EnvStrPrivate, Application::Settings.Private); + TryReadValue(data, "General", StrPort, EnvStrPort, Application::Settings.Port); + TryReadValue(data, "General", StrMaxCars, EnvStrMaxCars, Application::Settings.MaxCars); + TryReadValue(data, "General", StrMaxPlayers, EnvStrMaxPlayers, Application::Settings.MaxPlayers); + TryReadValue(data, "General", StrMap, EnvStrMap, Application::Settings.MapName); + TryReadValue(data, "General", StrName, EnvStrName, Application::Settings.ServerName); + TryReadValue(data, "General", StrDescription, EnvStrDescription, Application::Settings.ServerDesc); + TryReadValue(data, "General", StrResourceFolder, EnvStrResourceFolder, Application::Settings.Resource); + TryReadValue(data, "General", StrAuthKey, EnvStrAuthKey, Application::Settings.Key); + TryReadValue(data, "General", StrLogChat, EnvStrLogChat, Application::Settings.LogChat); + TryReadValue(data, "General", StrPassword, "", Application::Settings.Password); // Misc - TryReadValue(data, "Misc", StrSendErrors, Application::Settings.SendErrors); - TryReadValue(data, "Misc", StrHideUpdateMessages, Application::Settings.HideUpdateMessages); - TryReadValue(data, "Misc", StrSendErrorsMessageEnabled, Application::Settings.SendErrorsMessageEnabled); + TryReadValue(data, "Misc", StrSendErrors, "", Application::Settings.SendErrors); + TryReadValue(data, "Misc", StrHideUpdateMessages, "", Application::Settings.HideUpdateMessages); + TryReadValue(data, "Misc", StrSendErrorsMessageEnabled, "", Application::Settings.SendErrorsMessageEnabled); // HTTP - TryReadValue(data, "HTTP", StrSSLKeyPath, Application::Settings.SSLKeyPath); - TryReadValue(data, "HTTP", StrSSLCertPath, Application::Settings.SSLCertPath); - TryReadValue(data, "HTTP", StrHTTPServerPort, Application::Settings.HTTPServerPort); - TryReadValue(data, "HTTP", StrHTTPServerIP, Application::Settings.HTTPServerIP); - TryReadValue(data, "HTTP", StrHTTPServerEnabled, Application::Settings.HTTPServerEnabled); - TryReadValue(data, "HTTP", StrHTTPServerUseSSL, Application::Settings.HTTPServerUseSSL); + TryReadValue(data, "HTTP", StrSSLKeyPath, "", Application::Settings.SSLKeyPath); + TryReadValue(data, "HTTP", StrSSLCertPath, "", Application::Settings.SSLCertPath); + TryReadValue(data, "HTTP", StrHTTPServerPort, "", Application::Settings.HTTPServerPort); + TryReadValue(data, "HTTP", StrHTTPServerIP, "", Application::Settings.HTTPServerIP); + TryReadValue(data, "HTTP", StrHTTPServerEnabled, "", Application::Settings.HTTPServerEnabled); + TryReadValue(data, "HTTP", StrHTTPServerUseSSL, "", Application::Settings.HTTPServerUseSSL); } catch (const std::exception& err) { beammp_error("Error parsing config file value: " + std::string(err.what())); mFailed = true; From 221f4910199b53f84794b8457a2f08e004228b91 Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Mon, 25 Dec 2023 16:19:53 +0100 Subject: [PATCH 2/2] return early after reading ENV in config --- src/TConfig.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/TConfig.cpp b/src/TConfig.cpp index 11d5f79..efb18c7 100644 --- a/src/TConfig.cpp +++ b/src/TConfig.cpp @@ -175,6 +175,7 @@ void TConfig::TryReadValue(toml::value& Table, const std::string& Category, cons if (!Env.empty()) { if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { OutValue = std::string(envp); + return; } } if (Table[Category.c_str()][Key.data()].is_string()) { @@ -187,6 +188,7 @@ void TConfig::TryReadValue(toml::value& Table, const std::string& Category, cons if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { auto Str = std::string(envp); OutValue = Str == "1" || Str == "true"; + return; } } if (Table[Category.c_str()][Key.data()].is_boolean()) { @@ -198,6 +200,7 @@ void TConfig::TryReadValue(toml::value& Table, const std::string& Category, cons if (!Env.empty()) { if (const char* envp = std::getenv(Env.data()); envp != nullptr && std::strcmp(envp, "") != 0) { OutValue = int(std::strtol(envp, nullptr, 10)); + return; } } if (Table[Category.c_str()][Key.data()].is_integer()) {