diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e86b6b2..baabd36 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,6 @@ --- name: Bug report about: Create a report to help us improve -title: "[Bug] Enter issue title here" labels: bug assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 40f750b..20b75c1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,8 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: "[Feature Request]" -labels: enhancement +labels: feature assignees: '' --- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9b7de8c..5903e2c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -47,14 +47,20 @@ jobs: name: BeamMP-Server-debian path: ./bin/BeamMP-Server + - name: Archive server debug info artifact + uses: actions/upload-artifact@v2 + with: + name: BeamMP-Server-debian.debug + path: ./bin/BeamMP-Server.debug + - name: Build Tests run: bash ./scripts/debian-11/3-build-tests.sh - - name: Archive server tests artifact - uses: actions/upload-artifact@v2 - with: - name: BeamMP-Server-debian-tests - path: ./bin/BeamMP-Server-tests + - name: Install Runtime Dependencies + run: bash ./scripts/debian-11/4-install-runtime-deps.sh + + - name: Test + run: ./bin/BeamMP-Server-tests ubuntu-22-04-build: runs-on: ubuntu-latest @@ -101,51 +107,17 @@ jobs: name: BeamMP-Server-ubuntu path: ./bin/BeamMP-Server + - name: Archive server debug info artifact + uses: actions/upload-artifact@v2 + with: + name: BeamMP-Server-ubuntu.debug + path: ./bin/BeamMP-Server.debug + - name: Build Tests run: bash ./scripts/ubuntu-22.04/3-build-tests.sh - - name: Archive server tests artifact - uses: actions/upload-artifact@v2 - with: - name: BeamMP-Server-ubuntu-tests - path: ./bin/BeamMP-Server-tests - - run-debian-11-tests: - needs: debian-11-build - runs-on: ubuntu-latest - container: - image: debian:11 - steps: - - uses: actions/download-artifact@master - with: - name: BeamMP-Server-debian-tests - - name: Install Runtime Dependencies - run: | - apt-get update -y - apt-get install -y liblua5.3-0 + run: bash ./scripts/ubuntu-22.04/4-install-runtime-deps.sh - name: Test - run: | - chmod +x ./BeamMP-Server-tests - ./BeamMP-Server-tests - - run-ubuntu-22-04-tests: - needs: ubuntu-22-04-build - runs-on: ubuntu-latest - container: - image: ubuntu:22.04 - steps: - - uses: actions/download-artifact@master - with: - name: BeamMP-Server-ubuntu-tests - - - name: Install Runtime Dependencies - run: | - apt-get update -y - apt-get install -y liblua5.3-0 - - - name: Test - run: | - chmod +x ./BeamMP-Server-tests - ./BeamMP-Server-tests + run: ./bin/BeamMP-Server-tests \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1105fd5..46ae3df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,6 +83,17 @@ jobs: asset_path: ./bin/BeamMP-Server asset_name: BeamMP-Server-debian asset_content_type: application/x-elf + + - name: Upload Debug Info + id: upload-debug-info + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./bin/BeamMP-Server.debug + asset_name: debuginfo-debian.debug + asset_content_type: application/x-elf upload-release-files-ubuntu-22-04: name: Build and upload Ubuntu 22.04 Release Files @@ -131,6 +142,17 @@ jobs: asset_name: BeamMP-Server-ubuntu asset_content_type: application/x-elf + - name: Upload Debug Info + id: upload-debug-info + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./bin/BeamMP-Server.debug + asset_name: debuginfo-ubuntu.debug + asset_content_type: application/x-elf + upload-release-files-windows: name: Build and upload Windows Release Files runs-on: windows-latest diff --git a/README.md b/README.md index 558a471..fac027a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ The server is the point through which all clients communicate. You can write Lua Feel free to ask any questions via the following channels: -- **IRC**: `#beammp` on [irc.libera.chat](https://web.libera.chat/) - **Discord**: [click for invite](https://discord.gg/beammp) - **BeamMP Forum**: [BeamMP Forum Support](https://forum.beammp.com/c/support/33) diff --git a/include/Common.h b/include/Common.h index 9608150..fab1d30 100644 --- a/include/Common.h +++ b/include/Common.h @@ -76,7 +76,7 @@ public: static void RegisterShutdownHandler(const TShutdownHandler& Handler); // Causes all threads to finish up and exit gracefull gracefully static void GracefullyShutdown(); - static TConsole& Console() { return *mConsole; } + static TConsole& Console() { return mConsole; } static std::string ServerVersionString(); static const Version& ServerVersion() { return mVersion; } static uint8_t ClientMajorVersion() { return 2; } @@ -102,9 +102,7 @@ public: static void SleepSafeSeconds(size_t Seconds); static void InitializeConsole() { - if (!mConsole) { - mConsole = std::make_unique(); - } + mConsole.InitializeCommandline(); } enum class Status { @@ -130,13 +128,13 @@ private: static inline SystemStatusMap mSystemStatusMap {}; static inline std::mutex mSystemStatusMapMutex {}; static inline std::string mPPS; - static inline std::unique_ptr mConsole; + static inline TConsole mConsole; static inline std::shared_mutex mShutdownMtx {}; static inline bool mShutdown { false }; static inline std::mutex mShutdownHandlersMutex {}; static inline std::deque mShutdownHandlers {}; - static inline Version mVersion { 3, 1, 3 }; + static inline Version mVersion { 3, 2, 0 }; }; std::string ThreadName(bool DebugModeOverride = false); diff --git a/include/TConsole.h b/include/TConsole.h index eb733de..1f244ee 100644 --- a/include/TConsole.h +++ b/include/TConsole.h @@ -17,12 +17,15 @@ class TConsole { public: TConsole(); + // Initializes the commandline app to take over I/O + void InitializeCommandline(); + void Write(const std::string& str); void WriteRaw(const std::string& str); void InitializeLuaConsole(TLuaEngine& Engine); void BackupOldLog(); void StartLoggingToFile(); - Commandline& Internal() { return mCommandline; } + Commandline& Internal() { return *mCommandline; } private: void RunAsCommand(const std::string& cmd, bool IgnoreNotACommand = false); @@ -56,7 +59,7 @@ private: { "say", [this](const auto&, const auto&) { Command_Say(""); } }, // shouldn't actually be called }; - Commandline mCommandline; + std::unique_ptr mCommandline { nullptr }; std::vector mCachedLuaHistory; std::vector mCachedRegularHistory; TLuaEngine* mLuaEngine { nullptr }; diff --git a/scripts/debian-11/2-configure.sh b/scripts/debian-11/2-configure.sh index d1ad553..a1efec9 100755 --- a/scripts/debian-11/2-configure.sh +++ b/scripts/debian-11/2-configure.sh @@ -2,4 +2,4 @@ set -ex -cmake . -B bin $1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -s -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none -Wl,-z,noseparate-code -ffunction-sections -fdata-sections -Wl,--gc-sections" -DBeamMP-Server_ENABLE_LTO=ON +cmake . -B bin $1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -g -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none -Wl,-z,noseparate-code -ffunction-sections -fdata-sections -Wl,--gc-sections" -DBeamMP-Server_ENABLE_LTO=ON diff --git a/scripts/debian-11/3-build.sh b/scripts/debian-11/3-build.sh index 28fee9b..4671942 100755 --- a/scripts/debian-11/3-build.sh +++ b/scripts/debian-11/3-build.sh @@ -3,3 +3,8 @@ set -ex cmake --build bin --parallel -t BeamMP-Server + +objcopy --only-keep-debug bin/BeamMP-Server bin/BeamMP-Server.debug +objcopy --add-gnu-debuglink bin/BeamMP-Server bin/BeamMP-Server.debug + +strip -s bin/BeamMP-Server diff --git a/scripts/ubuntu-22.04/2-configure.sh b/scripts/ubuntu-22.04/2-configure.sh index d1ad553..a1efec9 100755 --- a/scripts/ubuntu-22.04/2-configure.sh +++ b/scripts/ubuntu-22.04/2-configure.sh @@ -2,4 +2,4 @@ set -ex -cmake . -B bin $1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -s -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none -Wl,-z,noseparate-code -ffunction-sections -fdata-sections -Wl,--gc-sections" -DBeamMP-Server_ENABLE_LTO=ON +cmake . -B bin $1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -g -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none -Wl,-z,noseparate-code -ffunction-sections -fdata-sections -Wl,--gc-sections" -DBeamMP-Server_ENABLE_LTO=ON diff --git a/scripts/ubuntu-22.04/3-build.sh b/scripts/ubuntu-22.04/3-build.sh index 28fee9b..4671942 100755 --- a/scripts/ubuntu-22.04/3-build.sh +++ b/scripts/ubuntu-22.04/3-build.sh @@ -3,3 +3,8 @@ set -ex cmake --build bin --parallel -t BeamMP-Server + +objcopy --only-keep-debug bin/BeamMP-Server bin/BeamMP-Server.debug +objcopy --add-gnu-debuglink bin/BeamMP-Server bin/BeamMP-Server.debug + +strip -s bin/BeamMP-Server diff --git a/src/TConfig.cpp b/src/TConfig.cpp index 928ae1a..cc69c85 100644 --- a/src/TConfig.cpp +++ b/src/TConfig.cpp @@ -26,14 +26,6 @@ static constexpr std::string_view StrSendErrors = "SendErrors"; static constexpr std::string_view StrSendErrorsMessageEnabled = "SendErrorsShowMessage"; static constexpr std::string_view StrHideUpdateMessages = "ImScaredOfUpdates"; -// HTTP -static constexpr std::string_view StrHTTPServerEnabled = "HTTPServerEnabled"; -static constexpr std::string_view StrHTTPServerUseSSL = "UseSSL"; -static constexpr std::string_view StrSSLKeyPath = "SSLKeyPath"; -static constexpr std::string_view StrSSLCertPath = "SSLCertPath"; -static constexpr std::string_view StrHTTPServerPort = "HTTPServerPort"; -static constexpr std::string_view StrHTTPServerIP = "HTTPServerIP"; - TEST_CASE("TConfig::TConfig") { const std::string CfgFile = "beammp_server_testconfig.toml"; fs::remove(CfgFile); @@ -57,7 +49,6 @@ TEST_CASE("TConfig::TConfig") { const auto table = toml::parse(CfgFile); CHECK(table.at("General").is_table()); CHECK(table.at("Misc").is_table()); - CHECK(table.at("HTTP").is_table()); fs::remove(CfgFile); } @@ -119,16 +110,6 @@ void TConfig::FlushToFile() { SetComment(data["Misc"][StrSendErrors.data()].comments(), " You can turn on/off the SendErrors message you get on startup here"); data["Misc"][StrSendErrorsMessageEnabled.data()] = Application::Settings.SendErrorsMessageEnabled; SetComment(data["Misc"][StrSendErrorsMessageEnabled.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`"); - // HTTP - data["HTTP"][StrSSLKeyPath.data()] = Application::Settings.SSLKeyPath; - data["HTTP"][StrSSLCertPath.data()] = Application::Settings.SSLCertPath; - data["HTTP"][StrHTTPServerPort.data()] = Application::Settings.HTTPServerPort; - SetComment(data["HTTP"][StrHTTPServerIP.data()].comments(), " Which IP to listen on. Pick 0.0.0.0 for a public-facing server with no specific IP, and 127.0.0.1 or 'localhost' for a local server."); - data["HTTP"][StrHTTPServerIP.data()] = Application::Settings.HTTPServerIP; - data["HTTP"][StrHTTPServerUseSSL.data()] = Application::Settings.HTTPServerUseSSL; - SetComment(data["HTTP"][StrHTTPServerUseSSL.data()].comments(), " Recommended to have enabled for servers which face the internet. With SSL the server will serve https and requires valid key and cert files"); - data["HTTP"][StrHTTPServerEnabled.data()] = Application::Settings.HTTPServerEnabled; - SetComment(data["HTTP"][StrHTTPServerEnabled.data()].comments(), " Enables the internal HTTP server"); std::stringstream Ss; Ss << "# This is the BeamMP-Server config file.\n" "# Help & Documentation: `https://wiki.beammp.com/en/home/server-maintenance`\n" @@ -201,13 +182,6 @@ void TConfig::ParseFromFile(std::string_view name) { 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); } catch (const std::exception& err) { beammp_error("Error parsing config file value: " + std::string(err.what())); mFailed = true; @@ -243,10 +217,6 @@ void TConfig::PrintDebug() { beammp_debug(std::string(StrTags) + ": \"" + Application::Settings.ServerTags + "\""); beammp_debug(std::string(StrLogChat) + ": \"" + (Application::Settings.LogChat ? "true" : "false") + "\""); beammp_debug(std::string(StrResourceFolder) + ": \"" + Application::Settings.Resource + "\""); - beammp_debug(std::string(StrSSLKeyPath) + ": \"" + Application::Settings.SSLKeyPath + "\""); - beammp_debug(std::string(StrSSLCertPath) + ": \"" + Application::Settings.SSLCertPath + "\""); - beammp_debug(std::string(StrHTTPServerPort) + ": \"" + std::to_string(Application::Settings.HTTPServerPort) + "\""); - beammp_debug(std::string(StrHTTPServerIP) + ": \"" + Application::Settings.HTTPServerIP + "\""); // special! beammp_debug("Key Length: " + std::to_string(Application::Settings.Key.length()) + ""); beammp_debug("Password Protected: " + std::string(Application::Settings.Password.empty() ? "false" : "true")); diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 56d6e05..cde978e 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -157,13 +157,13 @@ void TConsole::ChangeToLuaConsole(const std::string& LuaStateId) { mIsLuaConsole = true; if (mStateId != mDefaultStateId) { Application::Console().WriteRaw("Attached to Lua state '" + mStateId + "'. For help, type `:help`. To detach, type `:exit`"); - mCommandline.set_prompt("lua @" + LuaStateId + "> "); + mCommandline->set_prompt("lua @" + LuaStateId + "> "); } else { Application::Console().WriteRaw("Attached to Lua. For help, type `:help`. To detach, type `:exit`"); - mCommandline.set_prompt("lua> "); + mCommandline->set_prompt("lua> "); } - mCachedRegularHistory = mCommandline.history(); - mCommandline.set_history(mCachedLuaHistory); + mCachedRegularHistory = mCommandline->history(); + mCommandline->set_history(mCachedLuaHistory); } } @@ -175,9 +175,9 @@ void TConsole::ChangeToRegularConsole() { } else { Application::Console().WriteRaw("Detached from Lua."); } - mCachedLuaHistory = mCommandline.history(); - mCommandline.set_history(mCachedRegularHistory); - mCommandline.set_prompt("> "); + mCachedLuaHistory = mCommandline->history(); + mCommandline->set_history(mCachedRegularHistory); + mCommandline->set_prompt("> "); mStateId = mDefaultStateId; } } @@ -257,7 +257,7 @@ void TConsole::Command_Clear(const std::string&, const std::vector& if (!EnsureArgsCount(args, 0, size_t(-1))) { return; } - mCommandline.write("\x1b[;H\x1b[2J"); + mCommandline->write("\x1b[;H\x1b[2J"); } void TConsole::Command_Kick(const std::string&, const std::vector& args) { @@ -589,16 +589,20 @@ Commands } TConsole::TConsole() { - mCommandline.enable_history(); - mCommandline.set_history_limit(20); - mCommandline.set_prompt("> "); +} + +void TConsole::InitializeCommandline() { + mCommandline = std::make_unique(); + mCommandline->enable_history(); + mCommandline->set_history_limit(20); + mCommandline->set_prompt("> "); BackupOldLog(); - mCommandline.on_command = [this](Commandline& c) { + mCommandline->on_command = [this](Commandline& c) { try { auto TrimmedCmd = c.get_command(); TrimmedCmd = TrimString(TrimmedCmd); auto [cmd, args] = ParseCommand(TrimmedCmd); - mCommandline.write(mCommandline.prompt() + TrimmedCmd); + mCommandline->write(mCommandline->prompt() + TrimmedCmd); if (mIsLuaConsole) { if (!mLuaEngine) { beammp_info("Lua not started yet, please try again in a second"); @@ -633,7 +637,7 @@ TConsole::TConsole() { beammp_error("Console died with: " + std::string(e.what()) + ". This could be a fatal error and could cause the server to terminate."); } }; - mCommandline.on_autocomplete = [this](Commandline&, std::string stub, int) { + mCommandline->on_autocomplete = [this](Commandline&, std::string stub, int) { std::vector suggestions; try { if (mIsLuaConsole) { // if lua @@ -703,11 +707,21 @@ TConsole::TConsole() { void TConsole::Write(const std::string& str) { auto ToWrite = GetDate() + str; - mCommandline.write(ToWrite); + // allows writing to stdout without an initialized console + if (mCommandline) { + mCommandline->write(ToWrite); + } else { + std::cout << ToWrite << std::endl; + } } void TConsole::WriteRaw(const std::string& str) { - mCommandline.write(str); + // allows writing to stdout without an initialized console + if (mCommandline) { + mCommandline->write(str); + } else { + std::cout << str << std::endl; + } } void TConsole::InitializeLuaConsole(TLuaEngine& Engine) { diff --git a/src/TPluginMonitor.cpp b/src/TPluginMonitor.cpp index 3332ae1..93686e4 100644 --- a/src/TPluginMonitor.cpp +++ b/src/TPluginMonitor.cpp @@ -1,6 +1,7 @@ #include "TPluginMonitor.h" #include "TLuaEngine.h" +#include TPluginMonitor::TPluginMonitor(const fs::path& Path, std::shared_ptr Engine) : mEngine(Engine) @@ -9,7 +10,7 @@ TPluginMonitor::TPluginMonitor(const fs::path& Path, std::shared_ptr if (!fs::exists(mPath)) { fs::create_directories(mPath); } - for (const auto& Entry : fs::recursive_directory_iterator(mPath)) { + for (const auto& Entry : fs::recursive_directory_iterator(mPath, fs::directory_options::follow_directory_symlink)) { // TODO: trigger an event when a subfolder file changes if (Entry.is_regular_file()) { mFileTimes[Entry.path().string()] = fs::last_write_time(Entry.path()); diff --git a/src/main.cpp b/src/main.cpp index 4a027f1..d73c6c1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,7 +69,6 @@ int main(int argc, char** argv) { int BeamMPServerMain(MainArguments Arguments) { setlocale(LC_ALL, "C"); - Application::InitializeConsole(); ArgsParser Parser; Parser.RegisterArgument({ "help" }, ArgsParser::NONE); Parser.RegisterArgument({ "version" }, ArgsParser::NONE); @@ -80,12 +79,10 @@ int BeamMPServerMain(MainArguments Arguments) { return 1; } if (Parser.FoundArgument({ "help" })) { - Application::Console().Internal().set_prompt(""); Application::Console().WriteRaw(sCommandlineArguments); return 0; } if (Parser.FoundArgument({ "version" })) { - Application::Console().Internal().set_prompt(""); Application::Console().WriteRaw("BeamMP-Server v" + Application::ServerVersionString()); return 0; } @@ -109,11 +106,22 @@ int BeamMPServerMain(MainArguments Arguments) { } } } + + TConfig Config(ConfigPath); + + if (Config.Failed()) { + beammp_info("Closing in 10 seconds"); + // loop to make it possible to ctrl+c instead + for (size_t i = 0; i < 20; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + return 1; + } + Application::InitializeConsole(); + Application::Console().StartLoggingToFile(); Application::SetSubsystemStatus("Main", Application::Status::Starting); - Application::Console().StartLoggingToFile(); - SetupSignalHandlers(); bool Shutdown = false; @@ -128,20 +136,11 @@ int BeamMPServerMain(MainArguments Arguments) { }); TServer Server(Arguments.List); - TConfig Config(ConfigPath); + auto LuaEngine = std::make_shared(); LuaEngine->SetServer(&Server); Application::Console().InitializeLuaConsole(*LuaEngine); - if (Config.Failed()) { - beammp_info("Closing in 10 seconds"); - // loop to make it possible to ctrl+c instead - for (size_t i = 0; i < 20; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - return 1; - } - RegisterThread("Main"); beammp_trace("Running in debug mode on a debug build");