Fix various issues and crashes

This commit is contained in:
Lion Kortlepel 2021-12-06 12:28:52 +01:00
parent 279c93179c
commit 0f74eca2ee
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
9 changed files with 96 additions and 66 deletions

View File

@ -82,9 +82,32 @@ public:
static std::array<uint8_t, 3> VersionStrToInts(const std::string& str);
static bool IsOutdated(const Version& Current, const Version& Newest);
static void InitializeConsole() {
if (!mConsole) {
mConsole = std::make_unique<TConsole>();
}
}
enum class Status {
Starting,
Good,
Bad,
};
using SystemStatusMap = std::unordered_map<std::string /* system name */, Status /* status */>;
static const SystemStatusMap& GetSubsystemStatuses() {
return mSystemStatusMap;
}
static void SetSubsystemStatus(const std::string& Subsystem, Status status) {
mSystemStatusMap[Subsystem] = status;
}
private:
static inline SystemStatusMap mSystemStatusMap {};
static inline std::string mPPS;
static std::unique_ptr<TConsole> mConsole;
static inline std::unique_ptr<TConsole> mConsole;
static inline std::mutex mShutdownHandlersMutex {};
static inline std::deque<TShutdownHandler> mShutdownHandlers {};

View File

@ -91,14 +91,14 @@ static auto w_printf_s = [](const char* fmt, ...) {
va_end(args);
};
static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) {
static auto w_sprintf_s = [](char* buf, size_t, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
};
static auto w_sprintf_s_ret = [](char* buf, size_t buf_size, const char* fmt, ...) {
static auto w_sprintf_s_ret = [](char* buf, size_t, const char* fmt, ...) {
int ret;
va_list args;
va_start(args, fmt);

View File

@ -3,12 +3,16 @@
#include <Common.h>
#include <IThreaded.h>
#include <filesystem>
#include <httplib.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <string>
#include <unordered_map>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#include <httplib.h>
#pragma GCC diagnostic pop
namespace fs = std::filesystem;
namespace Crypto {
@ -36,12 +40,6 @@ namespace Server {
void operator()();
private:
/**
* the shared pointer is necessary because httplib is a blocking library and due lacking thread-safety
* will "forget" about its environment, when configured across multiple threads.
* So we need to able to start the server (make it "listen()") in a single Thread.
*/
std::shared_ptr<httplib::SSLServer> mHttpLibServerInstancePtr;
std::thread mThread;
};
// todo: all of these functions are likely unsafe,

View File

@ -16,19 +16,19 @@ public:
void InitializeLuaConsole(TLuaEngine& Engine);
void BackupOldLog();
Commandline& Internal() { return mCommandline; }
private:
void RunAsCommand(const std::string& cmd, bool IgnoreNotACommand = false);
void ChangeToLuaConsole(const std::string& LuaStateId);
void ChangeToRegularConsole();
void Command_Lua(const std::string& cmd);
void Command_Help(const std::string& cmd);
void Command_Kick(const std::string& cmd);
void Command_Say(const std::string& cmd);
void Command_List(const std::string& cmd);
void Command_Status(const std::string& cmd);
Commandline mCommandline;
std::vector<std::string> mCachedLuaHistory;
std::vector<std::string> mCachedRegularHistory;

View File

@ -13,7 +13,6 @@
#include "Http.h"
Application::TSettings Application::Settings = {};
std::unique_ptr<TConsole> Application::mConsole = std::make_unique<TConsole>();
void Application::RegisterShutdownHandler(const TShutdownHandler& Handler) {
std::unique_lock Lock(mShutdownHandlersMutex);

View File

@ -270,14 +270,14 @@ Http::Server::THttpServerInstance::THttpServerInstance() {
void Http::Server::THttpServerInstance::operator()() {
beammp_info("HTTPS Server started on port " + std::to_string(Application::Settings.HTTPServerPort));
httplib::SSLServer HttpLibServerInstance { Application::Settings.SSLCertPath.c_str(), Application::Settings.SSLKeyPath.c_str() };
// todo: make this IP agnostic so people can set their own IP
mHttpLibServerInstancePtr = std::make_shared<httplib::SSLServer>(Application::Settings.SSLCertPath.c_str(), Application::Settings.SSLKeyPath.c_str());
mHttpLibServerInstancePtr->Get("/", [](const httplib::Request&, httplib::Response& res) {
HttpLibServerInstance.Get("/", [](const httplib::Request&, httplib::Response& res) {
res.set_content("<!DOCTYPE html><article><h1>Hello World!</h1><section><p>BeamMP Server can now serve HTTP requests!</p></section></article></html>", "text/html");
});
mHttpLibServerInstancePtr->Get("/health", [](const httplib::Request&, httplib::Response& res) {
HttpLibServerInstance.Get("/health", [](const httplib::Request&, httplib::Response& res) {
res.set_content("0", "text/plain");
res.status = 200;
});
mHttpLibServerInstancePtr->listen("0.0.0.0", Application::Settings.HTTPServerPort);
HttpLibServerInstance.listen("0.0.0.0", Application::Settings.HTTPServerPort);
}

View File

@ -42,6 +42,7 @@ TConfig::TConfig(const std::string& ConfigFileName)
ParseFromFile(mConfigFileName);
}
}
/**
* @brief Writes out the loaded application state into ServerConfig.toml
*

View File

@ -38,7 +38,7 @@ std::string GetDate() {
auto fraction = now - seconds;
size_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(fraction).count();
char fracstr[5];
std::sprintf(fracstr, "%0.3lu", ms);
std::sprintf(fracstr, "%03lu", ms);
date += fracstr;
date += "] ";
} else {
@ -99,6 +99,11 @@ void TConsole::BackupOldLog() {
void TConsole::ChangeToLuaConsole(const std::string& LuaStateId) {
if (!mIsLuaConsole) {
if (!mLuaEngine) {
beammp_error("Lua engine not initialized yet, please wait and try again");
return;
}
mLuaEngine->EnsureStateExists(mDefaultStateId, "Console");
mStateId = LuaStateId;
mIsLuaConsole = true;
if (mStateId != mDefaultStateId) {
@ -106,8 +111,8 @@ void TConsole::ChangeToLuaConsole(const std::string& LuaStateId) {
} else {
Application::Console().WriteRaw("Entered Lua console. To exit, type `exit()`");
}
//mCachedRegularHistory = mCommandline.history();
//mCommandline.set_history(mCachedLuaHistory);
// mCachedRegularHistory = mCommandline.history();
// mCommandline.set_history(mCachedLuaHistory);
mCommandline.set_prompt("lua> ");
}
}
@ -120,8 +125,8 @@ void TConsole::ChangeToRegularConsole() {
} else {
Application::Console().WriteRaw("Left Lua console.");
}
//mCachedLuaHistory = mCommandline.history();
//mCommandline.set_history(mCachedRegularHistory);
// mCachedLuaHistory = mCommandline.history();
// mCommandline.set_history(mCachedRegularHistory);
mCommandline.set_prompt("> ");
mStateId = mDefaultStateId;
}
@ -322,45 +327,45 @@ TConsole::TConsole() {
auto cmd = c.get_command();
cmd = TrimString(cmd);
mCommandline.write(mCommandline.prompt() + cmd);
if (!mLuaEngine) {
beammp_info("Lua not started yet, please try again in a second");
} else {
if (mIsLuaConsole) {
if (cmd == "exit()") {
ChangeToRegularConsole();
} else {
auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(cmd), "", "" });
while (!Future->Ready) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // TODO: Add a timeout
}
if (Future->Error) {
beammp_lua_error(Future->ErrorMessage);
}
}
if (mIsLuaConsole) {
if (!mLuaEngine) {
beammp_info("Lua not started yet, please try again in a second");
} else if (cmd == "exit()") {
ChangeToRegularConsole();
} else {
if (cmd == "exit") {
beammp_info("gracefully shutting down");
Application::GracefullyShutdown();
} else if (StringStartsWith(cmd, "lua")) {
Command_Lua(cmd);
} else if (StringStartsWith(cmd, "help")) {
RunAsCommand(cmd, true);
Command_Help(cmd);
} else if (StringStartsWith(cmd, "kick")) {
RunAsCommand(cmd, true);
Command_Kick(cmd);
} else if (StringStartsWith(cmd, "say")) {
RunAsCommand(cmd, true);
Command_Say(cmd);
} else if (StringStartsWith(cmd, "list")) {
RunAsCommand(cmd, true);
Command_List(cmd);
} else if (StringStartsWith(cmd, "status")) {
RunAsCommand(cmd, true);
Command_Status(cmd);
} else if (!cmd.empty()) {
RunAsCommand(cmd);
auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(cmd), "", "" });
while (!Future->Ready) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // TODO: Add a timeout
}
if (Future->Error) {
beammp_lua_error(Future->ErrorMessage);
}
}
} else {
if (!mLuaEngine) {
beammp_error("Attempted to run a command before Lua engine started. Please wait and try again.");
} else if (cmd == "exit") {
beammp_info("gracefully shutting down");
Application::GracefullyShutdown();
} else if (StringStartsWith(cmd, "lua")) {
Command_Lua(cmd);
} else if (StringStartsWith(cmd, "help")) {
RunAsCommand(cmd, true);
Command_Help(cmd);
} else if (StringStartsWith(cmd, "kick")) {
RunAsCommand(cmd, true);
Command_Kick(cmd);
} else if (StringStartsWith(cmd, "say")) {
RunAsCommand(cmd, true);
Command_Say(cmd);
} else if (StringStartsWith(cmd, "list")) {
RunAsCommand(cmd, true);
Command_List(cmd);
} else if (StringStartsWith(cmd, "status")) {
RunAsCommand(cmd, true);
Command_Status(cmd);
} else if (!cmd.empty()) {
RunAsCommand(cmd);
}
}
} catch (const std::exception& e) {
@ -380,5 +385,4 @@ void TConsole::WriteRaw(const std::string& str) {
void TConsole::InitializeLuaConsole(TLuaEngine& Engine) {
mLuaEngine = &Engine;
Engine.EnsureStateExists(mDefaultStateId, "Console");
}

View File

@ -77,6 +77,7 @@ int main(int argc, char** argv) {
int BeamMPServerMain(MainArguments Arguments) {
setlocale(LC_ALL, "C");
Application::InitializeConsole();
SetupSignalHandlers();
@ -131,6 +132,7 @@ int BeamMPServerMain(MainArguments Arguments) {
TConfig Config(ConfigPath);
TLuaEngine LuaEngine;
LuaEngine.SetServer(&Server);
Application::Console().InitializeLuaConsole(LuaEngine);
if (Config.Failed()) {
beammp_info("Closing in 10 seconds");
@ -146,13 +148,12 @@ int BeamMPServerMain(MainArguments Arguments) {
beammp_trace("Running in debug mode on a debug build");
Sentry.SetupUser();
Sentry.PrintWelcome();
TResourceManager ResourceManager;
TResourceManager ResourceManager;
TPPSMonitor PPSMonitor(Server);
THeartbeatThread Heartbeat(ResourceManager, Server);
TNetwork Network(Server, PPSMonitor, ResourceManager);
LuaEngine.SetNetwork(&Network);
PPSMonitor.SetNetwork(Network);
Application::Console().InitializeLuaConsole(LuaEngine);
Application::CheckForUpdates();
if (Application::Settings.HTTPServerEnabled) {
@ -160,11 +161,15 @@ int BeamMPServerMain(MainArguments Arguments) {
Http::Server::THttpServerInstance HttpServerInstance {};
}
beammp_debug("cert.pem is " + std::to_string(fs::file_size("cert.pem")) + " bytes");
beammp_debug("key.pem is " + std::to_string(fs::file_size("key.pem")) + " bytes");
RegisterThread("Main(Waiting)");
auto Statuses = Application::GetSubsystemStatuses();
for (const auto& NameStatusPair : Statuses) {
if (NameStatusPair.second != Application::Status::Good) {
beammp_info("not good: " + NameStatusPair.first);
}
}
while (!Shutdown) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}