mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-01 23:35:41 +00:00
Add an entry in serverconfig.toml for the time between update reminders (#329)
fix #321
This commit is contained in:
commit
8b94b1f0ef
@ -50,6 +50,7 @@ set(PRJ_HEADERS
|
|||||||
include/VehicleData.h
|
include/VehicleData.h
|
||||||
include/Env.h
|
include/Env.h
|
||||||
include/Profiling.h
|
include/Profiling.h
|
||||||
|
include/ChronoWrapper.h
|
||||||
)
|
)
|
||||||
# add all source files (.cpp) to this, except the one with main()
|
# add all source files (.cpp) to this, except the one with main()
|
||||||
set(PRJ_SOURCES
|
set(PRJ_SOURCES
|
||||||
@ -74,6 +75,7 @@ set(PRJ_SOURCES
|
|||||||
src/VehicleData.cpp
|
src/VehicleData.cpp
|
||||||
src/Env.cpp
|
src/Env.cpp
|
||||||
src/Profiling.cpp
|
src/Profiling.cpp
|
||||||
|
src/ChronoWrapper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Lua REQUIRED)
|
find_package(Lua REQUIRED)
|
||||||
@ -220,4 +222,4 @@ if(${PROJECT_NAME}_ENABLE_UNIT_TESTING)
|
|||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_link_options(${PROJECT_NAME}-tests PRIVATE "/SUBSYSTEM:CONSOLE")
|
target_link_options(${PROJECT_NAME}-tests PRIVATE "/SUBSYSTEM:CONSOLE")
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
endif()
|
endif()
|
||||||
|
8
include/ChronoWrapper.h
Normal file
8
include/ChronoWrapper.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ChronoWrapper {
|
||||||
|
std::chrono::high_resolution_clock::duration TimeFromStringWithLiteral(const std::string& time_str);
|
||||||
|
}
|
@ -83,6 +83,7 @@ public:
|
|||||||
std::string HTTPServerIP { "127.0.0.1" };
|
std::string HTTPServerIP { "127.0.0.1" };
|
||||||
bool HTTPServerUseSSL { false };
|
bool HTTPServerUseSSL { false };
|
||||||
bool HideUpdateMessages { false };
|
bool HideUpdateMessages { false };
|
||||||
|
std::string UpdateReminderTime { "30s" };
|
||||||
[[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); }
|
[[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
27
src/ChronoWrapper.cpp
Normal file
27
src/ChronoWrapper.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "ChronoWrapper.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
std::chrono::high_resolution_clock::duration ChronoWrapper::TimeFromStringWithLiteral(const std::string& time_str)
|
||||||
|
{
|
||||||
|
// const std::regex time_regex(R"((\d+\.{0,1}\d*)(min|ms|us|ns|[dhs]))"); //i.e one of: "25ns, 6us, 256ms, 2s, 13min, 69h, 356d" will get matched (only available in newer C++ versions)
|
||||||
|
const std::regex time_regex(R"((\d+\.{0,1}\d*)(min|[dhs]))"); //i.e one of: "2.01s, 13min, 69h, 356.69d" will get matched
|
||||||
|
std::smatch match;
|
||||||
|
float time_value;
|
||||||
|
if (!std::regex_search(time_str, match, time_regex)) return std::chrono::nanoseconds(0);
|
||||||
|
time_value = stof(match.str(1));
|
||||||
|
beammp_debugf("Parsed time was: {}{}", time_value, match.str(2));
|
||||||
|
if (match.str(2) == "d") {
|
||||||
|
return std::chrono::seconds((uint64_t)(time_value * 86400)); //86400 seconds in a day
|
||||||
|
}
|
||||||
|
else if (match.str(2) == "h") {
|
||||||
|
return std::chrono::seconds((uint64_t)(time_value * 3600)); //3600 seconds in an hour
|
||||||
|
}
|
||||||
|
else if (match.str(2) == "min") {
|
||||||
|
return std::chrono::seconds((uint64_t)(time_value * 60));
|
||||||
|
}
|
||||||
|
else if (match.str(2) == "s") {
|
||||||
|
return std::chrono::seconds((uint64_t)time_value);
|
||||||
|
}
|
||||||
|
return std::chrono::nanoseconds(0);
|
||||||
|
}
|
@ -28,6 +28,7 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "Compat.h"
|
#include "Compat.h"
|
||||||
#include "CustomAssert.h"
|
#include "CustomAssert.h"
|
||||||
@ -384,3 +385,4 @@ void SplitString(const std::string& str, const char delim, std::vector<std::stri
|
|||||||
out.push_back(str.substr(start, end - start));
|
out.push_back(str.substr(start, end - start));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ static constexpr std::string_view StrPassword = "Password";
|
|||||||
static constexpr std::string_view StrSendErrors = "SendErrors";
|
static constexpr std::string_view StrSendErrors = "SendErrors";
|
||||||
static constexpr std::string_view StrSendErrorsMessageEnabled = "SendErrorsShowMessage";
|
static constexpr std::string_view StrSendErrorsMessageEnabled = "SendErrorsShowMessage";
|
||||||
static constexpr std::string_view StrHideUpdateMessages = "ImScaredOfUpdates";
|
static constexpr std::string_view StrHideUpdateMessages = "ImScaredOfUpdates";
|
||||||
|
static constexpr std::string_view StrUpdateReminderTime = "UpdateReminderTime";
|
||||||
|
|
||||||
TEST_CASE("TConfig::TConfig") {
|
TEST_CASE("TConfig::TConfig") {
|
||||||
const std::string CfgFile = "beammp_server_testconfig.toml";
|
const std::string CfgFile = "beammp_server_testconfig.toml";
|
||||||
@ -140,6 +141,8 @@ void TConfig::FlushToFile() {
|
|||||||
// Misc
|
// Misc
|
||||||
data["Misc"][StrHideUpdateMessages.data()] = Application::Settings.HideUpdateMessages;
|
data["Misc"][StrHideUpdateMessages.data()] = Application::Settings.HideUpdateMessages;
|
||||||
SetComment(data["Misc"][StrHideUpdateMessages.data()].comments(), " Hides the periodic update message which notifies you of a new server version. You should really keep this on and always update as soon as possible. For more information visit https://wiki.beammp.com/en/home/server-maintenance#updating-the-server. An update message will always appear at startup regardless.");
|
SetComment(data["Misc"][StrHideUpdateMessages.data()].comments(), " Hides the periodic update message which notifies you of a new server version. You should really keep this on and always update as soon as possible. For more information visit https://wiki.beammp.com/en/home/server-maintenance#updating-the-server. An update message will always appear at startup regardless.");
|
||||||
|
data["Misc"][StrUpdateReminderTime.data()] = Application::Settings.UpdateReminderTime;
|
||||||
|
SetComment(data["Misc"][StrUpdateReminderTime.data()].comments(), " Specifies the time between update reminders. You can use any of \"s, min, h, d\" at the end to specify the units seconds, minutes, hours or days. So 30d or 0.5min will print the update message every 30 days or half a minute.");
|
||||||
data["Misc"][StrSendErrors.data()] = Application::Settings.SendErrors;
|
data["Misc"][StrSendErrors.data()] = Application::Settings.SendErrors;
|
||||||
SetComment(data["Misc"][StrSendErrors.data()].comments(), " If SendErrors is `true`, the server will send helpful info about crashes and other issues back to the BeamMP developers. This info may include your config, who is on your server at the time of the error, and similar general information. This kind of data is vital in helping us diagnose and fix issues faster. This has no impact on server performance. You can opt-out of this system by setting this to `false`");
|
SetComment(data["Misc"][StrSendErrors.data()].comments(), " If SendErrors is `true`, the server will send helpful info about crashes and other issues back to the BeamMP developers. This info may include your config, who is on your server at the time of the error, and similar general information. This kind of data is vital in helping us diagnose and fix issues faster. This has no impact on server performance. You can opt-out of this system by setting this to `false`");
|
||||||
data["Misc"][StrSendErrorsMessageEnabled.data()] = Application::Settings.SendErrorsMessageEnabled;
|
data["Misc"][StrSendErrorsMessageEnabled.data()] = Application::Settings.SendErrorsMessageEnabled;
|
||||||
@ -252,6 +255,7 @@ void TConfig::ParseFromFile(std::string_view name) {
|
|||||||
// Misc
|
// Misc
|
||||||
TryReadValue(data, "Misc", StrSendErrors, "", Application::Settings.SendErrors);
|
TryReadValue(data, "Misc", StrSendErrors, "", Application::Settings.SendErrors);
|
||||||
TryReadValue(data, "Misc", StrHideUpdateMessages, "", Application::Settings.HideUpdateMessages);
|
TryReadValue(data, "Misc", StrHideUpdateMessages, "", Application::Settings.HideUpdateMessages);
|
||||||
|
TryReadValue(data, "Misc", StrUpdateReminderTime, "", Application::Settings.UpdateReminderTime);
|
||||||
TryReadValue(data, "Misc", StrSendErrorsMessageEnabled, "", Application::Settings.SendErrorsMessageEnabled);
|
TryReadValue(data, "Misc", StrSendErrorsMessageEnabled, "", Application::Settings.SendErrorsMessageEnabled);
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
beammp_error("Error parsing config file value: " + std::string(err.what()));
|
beammp_error("Error parsing config file value: " + std::string(err.what()));
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
#include "Http.h"
|
#include "Http.h"
|
||||||
|
#include "ChronoWrapper.h"
|
||||||
//#include "SocketIO.h"
|
//#include "SocketIO.h"
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
#include <rapidjson/rapidjson.h>
|
#include <rapidjson/rapidjson.h>
|
||||||
@ -36,15 +37,17 @@ void THeartbeatThread::operator()() {
|
|||||||
static std::string Last;
|
static std::string Last;
|
||||||
|
|
||||||
static std::chrono::high_resolution_clock::time_point LastNormalUpdateTime = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point LastNormalUpdateTime = std::chrono::high_resolution_clock::now();
|
||||||
|
static std::chrono::high_resolution_clock::time_point LastUpdateReminderTime = std::chrono::high_resolution_clock::now();
|
||||||
bool isAuth = false;
|
bool isAuth = false;
|
||||||
size_t UpdateReminderCounter = 0;
|
std::chrono::high_resolution_clock::duration UpdateReminderTimePassed;
|
||||||
|
auto UpdateReminderTimeout = ChronoWrapper::TimeFromStringWithLiteral(Application::Settings.UpdateReminderTime);
|
||||||
while (!Application::IsShuttingDown()) {
|
while (!Application::IsShuttingDown()) {
|
||||||
++UpdateReminderCounter;
|
|
||||||
Body = GenerateCall();
|
Body = GenerateCall();
|
||||||
// a hot-change occurs when a setting has changed, to update the backend of that change.
|
// a hot-change occurs when a setting has changed, to update the backend of that change.
|
||||||
auto Now = std::chrono::high_resolution_clock::now();
|
auto Now = std::chrono::high_resolution_clock::now();
|
||||||
bool Unchanged = Last == Body;
|
bool Unchanged = Last == Body;
|
||||||
auto TimePassed = (Now - LastNormalUpdateTime);
|
auto TimePassed = (Now - LastNormalUpdateTime);
|
||||||
|
UpdateReminderTimePassed = (Now - LastUpdateReminderTime);
|
||||||
auto Threshold = Unchanged ? 30 : 5;
|
auto Threshold = Unchanged ? 30 : 5;
|
||||||
if (TimePassed < std::chrono::seconds(Threshold)) {
|
if (TimePassed < std::chrono::seconds(Threshold)) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
@ -129,7 +132,9 @@ void THeartbeatThread::operator()() {
|
|||||||
if (isAuth || Application::Settings.Private) {
|
if (isAuth || Application::Settings.Private) {
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
||||||
}
|
}
|
||||||
if (!Application::Settings.HideUpdateMessages && UpdateReminderCounter % 5) {
|
// beammp_debugf("Update reminder time passed: {}, Update reminder time: {}", UpdateReminderTimePassed.count(), UpdateReminderTimeout.count());
|
||||||
|
if (!Application::Settings.HideUpdateMessages && UpdateReminderTimePassed.count() > UpdateReminderTimeout.count()) {
|
||||||
|
LastUpdateReminderTime = std::chrono::high_resolution_clock::now();
|
||||||
Application::CheckForUpdates();
|
Application::CheckForUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user