This commit is contained in:
SaltySnail 2024-05-25 20:32:07 +02:00
parent 93192fd9b5
commit 29c3fed374
7 changed files with 63 additions and 5 deletions

View File

@ -50,6 +50,7 @@ set(PRJ_HEADERS
include/VehicleData.h
include/Env.h
include/Profiling.h
include/ChronoWrapper.h
)
# add all source files (.cpp) to this, except the one with main()
set(PRJ_SOURCES
@ -74,6 +75,7 @@ set(PRJ_SOURCES
src/VehicleData.cpp
src/Env.cpp
src/Profiling.cpp
src/ChronoWrapper.cpp
)
find_package(Lua REQUIRED)

8
include/ChronoWrapper.h Normal file
View 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);
}

View File

@ -83,6 +83,7 @@ public:
std::string HTTPServerIP { "127.0.0.1" };
bool HTTPServerUseSSL { false };
bool HideUpdateMessages { false };
std::string UpdateReminderTime { "3h" };
[[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); }
};
@ -151,7 +152,7 @@ private:
static inline std::mutex mShutdownHandlersMutex {};
static inline std::deque<TShutdownHandler> mShutdownHandlers {};
static inline Version mVersion { 3, 5, 0 };
static inline Version mVersion { 4, 5, 0 };
};
void SplitString(std::string const& str, const char delim, std::vector<std::string>& out);

36
src/ChronoWrapper.cpp Normal file
View File

@ -0,0 +1,36 @@
#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+)(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+\.*\d*)(min|[dhs]))"); //i.e one of: "2.01s, 13min, 69h, 356.69d" will get matched
std::smatch match;
int64_t time_value; //TODO: make time_value a float and figure out how to return that as the correct amount of nanoseconds in high_precision_clock::duration
if (!std::regex_search(time_str, match, time_regex)) return std::chrono::nanoseconds(0);
time_value = stoi(match.str(1));
beammp_debugf("Parsed time was: {}{}", time_value, match.str(2));
if (match.str(2) == "d") {
return std::chrono::days(time_value);
}
else if (match.str(2) == "h") {
return std::chrono::hours(time_value);
}
else if (match.str(2) == "min") {
return std::chrono::minutes(time_value);
}
else if (match.str(2) == "s") {
return std::chrono::seconds(time_value);
}
// else if (match.str(2) == "ms") {
// return std::chrono::milliseconds(time_value);
// }
// else if (match.str(2) == "us") {
// return std::chrono::microseconds(time_value);
// }
// else if (match.str(2) == "ns") {
// return std::chrono::nanoseconds(time_value);
// }
return std::chrono::nanoseconds(0);
}

View File

@ -28,6 +28,7 @@
#include <regex>
#include <sstream>
#include <thread>
#include <chrono>
#include "Compat.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));
}
}

View File

@ -57,6 +57,7 @@ static constexpr std::string_view StrPassword = "Password";
static constexpr std::string_view StrSendErrors = "SendErrors";
static constexpr std::string_view StrSendErrorsMessageEnabled = "SendErrorsShowMessage";
static constexpr std::string_view StrHideUpdateMessages = "ImScaredOfUpdates";
static constexpr std::string_view StrUpdateReminderTime = "UpdateReminderTime";
TEST_CASE("TConfig::TConfig") {
const std::string CfgFile = "beammp_server_testconfig.toml";
@ -140,6 +141,8 @@ void TConfig::FlushToFile() {
// Misc
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.");
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 5min will print the update message every 30 days or 5 minutes.");
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`");
data["Misc"][StrSendErrorsMessageEnabled.data()] = Application::Settings.SendErrorsMessageEnabled;
@ -252,6 +255,7 @@ void TConfig::ParseFromFile(std::string_view name) {
// Misc
TryReadValue(data, "Misc", StrSendErrors, "", Application::Settings.SendErrors);
TryReadValue(data, "Misc", StrHideUpdateMessages, "", Application::Settings.HideUpdateMessages);
TryReadValue(data, "Misc", StrUpdateReminderTime, "", Application::Settings.UpdateReminderTime);
TryReadValue(data, "Misc", StrSendErrorsMessageEnabled, "", Application::Settings.SendErrorsMessageEnabled);
} catch (const std::exception& err) {
beammp_error("Error parsing config file value: " + std::string(err.what()));

View File

@ -20,6 +20,7 @@
#include "Client.h"
#include "Http.h"
#include "ChronoWrapper.h"
//#include "SocketIO.h"
#include <rapidjson/document.h>
#include <rapidjson/rapidjson.h>
@ -36,15 +37,17 @@ void THeartbeatThread::operator()() {
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 LastUpdateReminderTime = std::chrono::high_resolution_clock::now();
bool isAuth = false;
size_t UpdateReminderCounter = 0;
std::chrono::high_resolution_clock::duration UpdateReminderTimePassed;
auto UpdateReminderTimeout = ChronoWrapper::TimeFromStringWithLiteral(Application::Settings.UpdateReminderTime);
while (!Application::IsShuttingDown()) {
++UpdateReminderCounter;
Body = GenerateCall();
// a hot-change occurs when a setting has changed, to update the backend of that change.
auto Now = std::chrono::high_resolution_clock::now();
bool Unchanged = Last == Body;
auto TimePassed = (Now - LastNormalUpdateTime);
UpdateReminderTimePassed = (Now - LastUpdateReminderTime);
auto Threshold = Unchanged ? 30 : 5;
if (TimePassed < std::chrono::seconds(Threshold)) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
@ -129,7 +132,9 @@ void THeartbeatThread::operator()() {
if (isAuth || Application::Settings.Private) {
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();
}
}