mirror of
https://github.com/SantaSpeen/BeamMP-Server.git
synced 2025-07-01 23:55:25 +00:00
Fix various issues and crashes
This commit is contained in:
parent
279c93179c
commit
0f74eca2ee
@ -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 {};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ TConfig::TConfig(const std::string& ConfigFileName)
|
||||
ParseFromFile(mConfigFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes out the loaded application state into ServerConfig.toml
|
||||
*
|
||||
|
@ -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");
|
||||
}
|
||||
|
15
src/main.cpp
15
src/main.cpp
@ -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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user