mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-07-14 18:55:58 +00:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| daa674f448 | |||
| a85fef15c2 | |||
| 359faee696 | |||
| 299004b14e | |||
| b09f5a401d | |||
| 8ce3be03a3 | |||
| 687b4e4235 | |||
| 86ad28abdc | |||
| a982d54202 | |||
| 5553aca0bb | |||
| beaea4f624 | |||
| a4f07c9a4d | |||
| dada8fe6bf | |||
| 36853ca683 | |||
| d969c4a2c2 | |||
| f26ca6b40d | |||
| b72de4bd0a | |||
| 9494bc70fb | |||
| 5c44a307bc | |||
| 754053e73f | |||
| 29f8d29e33 | |||
| e043361abb | |||
| fca5bbcec9 | |||
| 2a588954be | |||
| cd4129e05d | |||
| c42c748b37 | |||
| 179b33a7ab | |||
| 1b14206a3c | |||
| 0cf81cf3f4 | |||
| 801780bcb1 | |||
| 84d52578e0 | |||
| 3555cec5fe | |||
| 71efe30345 | |||
| 5df8aedf08 | |||
| c3ab4b729a | |||
| 464aa3b59f | |||
| cfe63198c7 |
@@ -44,4 +44,15 @@ jobs:
|
|||||||
name: BeamMP-Server.exe
|
name: BeamMP-Server.exe
|
||||||
path: ${{github.workspace}}/build-windows/Release/BeamMP-Server.exe
|
path: ${{github.workspace}}/build-windows/Release/BeamMP-Server.exe
|
||||||
|
|
||||||
|
- name: Build debug
|
||||||
|
working-directory: ${{github.workspace}}/build-windows
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cmake --build . --config Debug
|
||||||
|
|
||||||
|
- name: Archive debug artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: BeamMP-Server-debug.exe
|
||||||
|
path: ${{github.workspace}}/build-windows/Debug/BeamMP-Server.exe
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -21,4 +21,7 @@
|
|||||||
url = https://github.com/nih-at/libzip
|
url = https://github.com/nih-at/libzip
|
||||||
[submodule "deps/cpp-httplib"]
|
[submodule "deps/cpp-httplib"]
|
||||||
path = deps/cpp-httplib
|
path = deps/cpp-httplib
|
||||||
url = https://github.com/yhirose/cpp-httplib
|
url = https://github.com/yhirose/cpp-httplib
|
||||||
|
[submodule "deps/json"]
|
||||||
|
path = deps/json
|
||||||
|
url = https://github.com/nlohmann/json
|
||||||
|
|||||||
+20
-12
@@ -8,12 +8,15 @@ project(BeamMP-Server
|
|||||||
HOMEPAGE_URL https://beammp.com
|
HOMEPAGE_URL https://beammp.com
|
||||||
LANGUAGES CXX C)
|
LANGUAGES CXX C)
|
||||||
|
|
||||||
|
set(HTTPLIB_REQUIRE_OPENSSL ON)
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/rapidjson/include")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/rapidjson/include")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/websocketpp")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/websocketpp")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/commandline")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/commandline")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/sol2/include")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/sol2/include")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/cpp-httplib")
|
include_directories("${PROJECT_SOURCE_DIR}/deps/cpp-httplib")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/json/single_include")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps")
|
include_directories("${PROJECT_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT)
|
add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||||
@@ -38,9 +41,25 @@ set(SENTRY_BUILD_SHARED_LIBS OFF)
|
|||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(SENTRY_BUILD_RUNTIMESTATIC ON)
|
set(SENTRY_BUILD_RUNTIMESTATIC ON)
|
||||||
endif()
|
endif()
|
||||||
set(SENTRY_BACKEND breakpad)
|
message(STATUS "Checking for Sentry URL")
|
||||||
|
# this is set by the build system.
|
||||||
|
# IMPORTANT: if you're building from source, just leave this empty
|
||||||
|
if (NOT DEFINED BEAMMP_SECRET_SENTRY_URL)
|
||||||
|
message(WARNING "No sentry URL configured. Sentry logging is disabled for this build. \
|
||||||
|
This is not an error, and if you're building the BeamMP-Server yourself, this is expected and can be ignored.")
|
||||||
|
set(BEAMMP_SECRET_SENTRY_URL "")
|
||||||
|
set(SENTRY_BACKEND none)
|
||||||
|
else()
|
||||||
|
string(LENGTH ${BEAMMP_SECRET_SENTRY_URL} URL_LEN)
|
||||||
|
message(STATUS "Sentry URL is length ${URL_LEN}")
|
||||||
|
set(SENTRY_BACKEND breakpad)
|
||||||
|
endif()
|
||||||
add_subdirectory("deps/sentry-native")
|
add_subdirectory("deps/sentry-native")
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
|
||||||
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Setting compiler flags")
|
message(STATUS "Setting compiler flags")
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
||||||
@@ -58,17 +77,6 @@ elseif (UNIX)
|
|||||||
endif (SANITIZE)
|
endif (SANITIZE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Checking for Sentry URL")
|
|
||||||
# this is set by the build system.
|
|
||||||
# IMPORTANT: if you're building from source, just leave this empty
|
|
||||||
if (NOT DEFINED BEAMMP_SECRET_SENTRY_URL)
|
|
||||||
message(WARNING "No sentry URL configured. Sentry logging is disabled for this build. \
|
|
||||||
This is not an error, and if you're building the BeamMP-Server yourself, this is expected and can be ignored.")
|
|
||||||
set(BEAMMP_SECRET_SENTRY_URL "")
|
|
||||||
else()
|
|
||||||
string(LENGTH ${BEAMMP_SECRET_SENTRY_URL} URL_LEN)
|
|
||||||
message(STATUS "Sentry URL is length ${URL_LEN}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Adding local source dependencies")
|
message(STATUS "Adding local source dependencies")
|
||||||
# this has to happen before -DDEBUG since it wont compile properly with -DDEBUG
|
# this has to happen before -DDEBUG since it wont compile properly with -DDEBUG
|
||||||
|
|||||||
+13
-3
@@ -1,7 +1,17 @@
|
|||||||
# v2.4.0
|
# v3.0.1
|
||||||
|
|
||||||
|
- ADDED Backup URLs to UpdateCheck (will fail less often now)
|
||||||
|
- ADDED console cursor left and right movement (with arrow keys) and working HOME and END key (via github.com/lionkor/commandline)
|
||||||
|
- FIXED infinite snowmen / infinite unicycle spawning bug
|
||||||
|
- FIXED a bug where, when run with --working-directory, the Server.log would still be in the original directory
|
||||||
|
- FIXED a bug which could cause the plugin reload thread to spin at 100% if the reloaded plugin's didn't terminate
|
||||||
|
- FIXED an issue which would cause servers to crash on mod download via SIGPIPE on POSIX
|
||||||
|
- FIXED an issue which would cause servers to crash when checking if a vehicle is a unicycle
|
||||||
|
|
||||||
|
# v3.0.0
|
||||||
|
|
||||||
- CHANGED entire plugin Lua implementation (rewrite)
|
- CHANGED entire plugin Lua implementation (rewrite)
|
||||||
- CHANGED moved *almost all* functions into MP.\*
|
- CHANGED moved *almost all* Lua functions into MP.\*
|
||||||
- CHANGED console to use a custom language (type `help`, `list`, or `status`!)
|
- CHANGED console to use a custom language (type `help`, `list`, or `status`!)
|
||||||
- CHANGED all files of a Lua plugin to share a Lua state (no more state-per-file)
|
- CHANGED all files of a Lua plugin to share a Lua state (no more state-per-file)
|
||||||
- ADDED many new Lua API functions, which can be found at <https://wiki.beammp.com/en/Scripting/functions>
|
- ADDED many new Lua API functions, which can be found at <https://wiki.beammp.com/en/Scripting/functions>
|
||||||
@@ -14,7 +24,7 @@
|
|||||||
- ADDED dumping tables with `print()` (try it with `print(MP)`)
|
- ADDED dumping tables with `print()` (try it with `print(MP)`)
|
||||||
- ADDED `MP.GetOSName()`, `MP.CreateTimer()`, `MP.GetLuaMemoryUsage()` and many more (see <https://wiki.beammp.com/en/Scripting/functions>)
|
- ADDED `MP.GetOSName()`, `MP.CreateTimer()`, `MP.GetLuaMemoryUsage()` and many more (see <https://wiki.beammp.com/en/Scripting/functions>)
|
||||||
- ADDED `MP.Settings` table to make usage of `MP.Set()` easier
|
- ADDED `MP.Settings` table to make usage of `MP.Set()` easier
|
||||||
- ADDED `FS.*` table with common filesystem operations
|
- ADDED `FS.*` table with common filesystem operations (do `print(FS)` to see them!)
|
||||||
- FIXED i/o thread spin when stdout is /dev/null on linux
|
- FIXED i/o thread spin when stdout is /dev/null on linux
|
||||||
- FIXED removed extra whitespace infront of onChatMessage message
|
- FIXED removed extra whitespace infront of onChatMessage message
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
This is the server for the multiplayer mod **[BeamMP](https://beammp.com/)** for the game [BeamNG.drive](https://www.beamng.com/).
|
This is the server for the multiplayer mod **[BeamMP](https://beammp.com/)** for the game [BeamNG.drive](https://www.beamng.com/).
|
||||||
The server is the point throug which all clients communicate. You can write lua mods for the server, detailed instructions on the [BeamMP Wiki](https://wiki.beammp.com).
|
The server is the point throug which all clients communicate. You can write lua mods for the server, detailed instructions on the [BeamMP Wiki](https://wiki.beammp.com).
|
||||||
|
|
||||||
|
**For Linux, you __need__ the runtime dependencies, listed below under "prerequisites".**
|
||||||
|
|
||||||
## Support + Contact
|
## Support + Contact
|
||||||
|
|
||||||
Feel free to ask any questions via the following channels:
|
Feel free to ask any questions via the following channels:
|
||||||
@@ -48,7 +50,7 @@ You can find precompiled binaries under [Releases](https://github.com/BeamMP/Bea
|
|||||||
|
|
||||||
## Build Instructions
|
## Build Instructions
|
||||||
|
|
||||||
**__Do not compile from `master`. Always build from a release tag, i.e. `tags/v2.0`!__**
|
**__Do not compile from `master`. Always build from a release tag, i.e. `tags/v2.3.3`!__**
|
||||||
|
|
||||||
Currently only linux and windows are supported (generally). See [Releases](https://github.com/BeamMP/BeamMP-Server/releases/) for official binary releases. On systems to which we do not provide binaries (so anything but windows), you are allowed to compile the program and use it. Other restrictions, such as not being allowed to distribute those binaries, still apply (see [copyright notice](#copyright)).
|
Currently only linux and windows are supported (generally). See [Releases](https://github.com/BeamMP/BeamMP-Server/releases/) for official binary releases. On systems to which we do not provide binaries (so anything but windows), you are allowed to compile the program and use it. Other restrictions, such as not being allowed to distribute those binaries, still apply (see [copyright notice](#copyright)).
|
||||||
|
|
||||||
@@ -58,38 +60,47 @@ Currently only linux and windows are supported (generally). See [Releases](https
|
|||||||
|
|
||||||
Please use the prepackaged binaries in [Releases](https://github.com/BeamMP/BeamMP-Server/releases/).
|
Please use the prepackaged binaries in [Releases](https://github.com/BeamMP/BeamMP-Server/releases/).
|
||||||
|
|
||||||
Dependencies for windows can be installed with `vcpkg`, in which case the current dependencies are the `x64-windows-static` versions of `lua`, `zlib`, `rapidjson`, and `openssl`.
|
Dependencies for **windows** can be installed with `vcpkg`.
|
||||||
|
These are:
|
||||||
|
```
|
||||||
|
lua
|
||||||
|
zlib
|
||||||
|
rapidjson
|
||||||
|
openssl
|
||||||
|
websocketpp
|
||||||
|
curl
|
||||||
|
```
|
||||||
|
|
||||||
#### Linux / \*nix
|
#### Linux
|
||||||
|
|
||||||
These package names are in the debian / ubuntu style. Feel free to PR your own guide for a different distro.
|
These package names are in the debian / ubuntu style. Feel free to PR your own guide for a different distro.
|
||||||
|
|
||||||
- `git`
|
Runtime dependencies for **linux** are (debian/ubuntu):
|
||||||
- `make`
|
```
|
||||||
- `cmake`
|
libz-dev
|
||||||
- `g++`
|
rapidjson-dev
|
||||||
- `libcurl4-openssl-dev` or similar (search for `libcurl` and look for one with `-dev`)
|
liblua5.3
|
||||||
|
libssl-dev
|
||||||
Must support ISO C++17. If your distro's `g++` doesn't support C++17, chances are that it has a `g++-8` or `g++-10` package that does. If this is the case. you just need to run CMake with `-DCMAKE_CXX_COMPILER=g++-10` (replace `g++-10` with your compiler's name).
|
libwebsocketpp-dev
|
||||||
- `liblua5.3-dev`
|
libcurl4-openssl-dev
|
||||||
|
|
||||||
Any 5.x version should work, but 5.3 is what we officially use. Any other version might break in the future.
|
|
||||||
You can also use any version of `libluajit`, but the same applies regarding the version.
|
|
||||||
- `libz-dev`
|
|
||||||
- `rapidjson-dev`
|
|
||||||
- `libopenssl-dev` or `libssl-dev`
|
|
||||||
|
|
||||||
In the end you should end up with a command something like this:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
sudo apt install git make cmake g++-10 liblua5.3 libz-dev rapidjson-dev libopenssl-dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
In the end you should end up with a command something like this:
|
Build-time dependencies for **linux** are:
|
||||||
|
|
||||||
```sh
|
|
||||||
sudo apt install git make cmake g++-10 liblua5.3 libz-dev rapidjson-dev libopenssl-dev
|
|
||||||
```
|
```
|
||||||
|
git
|
||||||
|
make
|
||||||
|
cmake
|
||||||
|
g++
|
||||||
|
```
|
||||||
|
|
||||||
|
For other distributions (e.g. Arch) you want to find packages for:
|
||||||
|
- libz
|
||||||
|
- rapidjson
|
||||||
|
- lua5.3
|
||||||
|
- ssl / openssl
|
||||||
|
- websocketpp
|
||||||
|
- curl (with ssl support)
|
||||||
|
- \+ the build time dependencies from above
|
||||||
|
|
||||||
### How to build
|
### How to build
|
||||||
|
|
||||||
@@ -98,7 +109,7 @@ On windows, use git-bash for these commands. On Linux, these should work in your
|
|||||||
1. Make sure you have all [prerequisites](#prerequisites) installed
|
1. Make sure you have all [prerequisites](#prerequisites) installed
|
||||||
2. Clone the repository in a location of your choice with `git clone --recurse-submodules https://github.com/BeamMP/BeamMP-Server`.
|
2. Clone the repository in a location of your choice with `git clone --recurse-submodules https://github.com/BeamMP/BeamMP-Server`.
|
||||||
3. Ensure that all submodules are initialized by running `git submodule update --init --recursive`. Then change into the cloned directory by running `cd BeamMP-Server`.
|
3. Ensure that all submodules are initialized by running `git submodule update --init --recursive`. Then change into the cloned directory by running `cd BeamMP-Server`.
|
||||||
4. Checkout the branch of the release you want to compile (`master` is often unstable), for example `git checkout tags/v1.20` for version 1.20. You can find the latest version [here](https://github.com/BeamMP/BeamMP-Server/tags).
|
4. Checkout the branch of the release you want to compile (`master` is often unstable), for example `git checkout tags/v2.3.3` for version 2.3.3. You can find the latest version [here](https://github.com/BeamMP/BeamMP-Server/tags).
|
||||||
5. Run `cmake . -DCMAKE_BUILD_TYPE=Release` (with `.`)
|
5. Run `cmake . -DCMAKE_BUILD_TYPE=Release` (with `.`)
|
||||||
6. Run `make`
|
6. Run `make`
|
||||||
7. You will now have a `BeamMP-Server` file in your directory, which is executable with `./BeamMP-Server` (`.\BeamMP-Server.exe` for windows). Follow the (windows or linux, doesnt matter) instructions on the [wiki](https://wiki.beammp.com/en/home/Server_Mod) for further setup after installation (which we just did), such as port-forwarding and getting a key to actually run the server.
|
7. You will now have a `BeamMP-Server` file in your directory, which is executable with `./BeamMP-Server` (`.\BeamMP-Server.exe` for windows). Follow the (windows or linux, doesnt matter) instructions on the [wiki](https://wiki.beammp.com/en/home/Server_Mod) for further setup after installation (which we just did), such as port-forwarding and getting a key to actually run the server.
|
||||||
|
|||||||
Vendored
+1
-1
Submodule deps/commandline updated: 3d11606d02...71240f634b
Vendored
+1
-1
Submodule deps/cpp-httplib updated: 301faa074c...b324921c1a
+1
Submodule deps/json added at eb21824147
+10
-5
@@ -42,7 +42,7 @@ public:
|
|||||||
std::string Key {};
|
std::string Key {};
|
||||||
std::string SSLKeyPath { "./.ssl/HttpServer/key.pem" };
|
std::string SSLKeyPath { "./.ssl/HttpServer/key.pem" };
|
||||||
std::string SSLCertPath { "./.ssl/HttpServer/cert.pem" };
|
std::string SSLCertPath { "./.ssl/HttpServer/cert.pem" };
|
||||||
bool HTTPServerEnabled { true };
|
bool HTTPServerEnabled { false };
|
||||||
int MaxPlayers { 10 };
|
int MaxPlayers { 10 };
|
||||||
bool Private { true };
|
bool Private { true };
|
||||||
int MaxCars { 1 };
|
int MaxCars { 1 };
|
||||||
@@ -74,10 +74,15 @@ public:
|
|||||||
|
|
||||||
static TSettings Settings;
|
static TSettings Settings;
|
||||||
|
|
||||||
|
static std::vector<std::string> GetBackendUrlsInOrder() {
|
||||||
|
return {
|
||||||
|
"backend.beammp.com",
|
||||||
|
"backup1.beammp.com",
|
||||||
|
"backup2.beammp.com"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static std::string GetBackendUrlForAuth() { return "auth.beammp.com"; }
|
static std::string GetBackendUrlForAuth() { return "auth.beammp.com"; }
|
||||||
static std::string GetBackendHostname() { return "backend.beammp.com"; }
|
|
||||||
static std::string GetBackup1Hostname() { return "backup1.beammp.com"; }
|
|
||||||
static std::string GetBackup2Hostname() { return "backup2.beammp.com"; }
|
|
||||||
static std::string GetBackendUrlForSocketIO() { return "https://backend.beammp.com"; }
|
static std::string GetBackendUrlForSocketIO() { return "https://backend.beammp.com"; }
|
||||||
static void CheckForUpdates();
|
static void CheckForUpdates();
|
||||||
static std::array<uint8_t, 3> VersionStrToInts(const std::string& str);
|
static std::array<uint8_t, 3> VersionStrToInts(const std::string& str);
|
||||||
@@ -114,7 +119,7 @@ private:
|
|||||||
static inline std::mutex mShutdownHandlersMutex {};
|
static inline std::mutex mShutdownHandlersMutex {};
|
||||||
static inline std::deque<TShutdownHandler> mShutdownHandlers {};
|
static inline std::deque<TShutdownHandler> mShutdownHandlers {};
|
||||||
|
|
||||||
static inline Version mVersion { 2, 4, 0 };
|
static inline Version mVersion { 3, 0, 1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string ThreadName(bool DebugModeOverride = false);
|
std::string ThreadName(bool DebugModeOverride = false);
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ constexpr size_t RSA_DEFAULT_KEYLENGTH { 2048 };
|
|||||||
|
|
||||||
namespace Http {
|
namespace Http {
|
||||||
std::string GET(const std::string& host, int port, const std::string& target, unsigned int* status = nullptr);
|
std::string GET(const std::string& host, int port, const std::string& target, unsigned int* status = nullptr);
|
||||||
std::string POST(const std::string& host, int port, const std::string& target, const std::string& body, const std::string& ContentType, unsigned int* status = nullptr);
|
std::string POST(const std::string& host, int port, const std::string& target, const std::string& body, const std::string& ContentType, unsigned int* status = nullptr, const httplib::Headers& headers = {});
|
||||||
namespace Status {
|
namespace Status {
|
||||||
std::string ToString(int code);
|
std::string ToString(int code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,10 +133,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||||
|
std::vector<TLuaArgTypes> Arguments { TLuaArgTypes { std::forward<ArgsT>(Args) }... };
|
||||||
|
|
||||||
for (const auto& Event : mLuaEvents.at(EventName)) {
|
for (const auto& Event : mLuaEvents.at(EventName)) {
|
||||||
for (const auto& Function : Event.second) {
|
for (const auto& Function : Event.second) {
|
||||||
if (Event.first != IgnoreId) {
|
if (Event.first != IgnoreId) {
|
||||||
Results.push_back(EnqueueFunctionCall(Event.first, Function, { TLuaArgTypes { std::forward<ArgsT>(Args) }... }));
|
Results.push_back(EnqueueFunctionCall(Event.first, Function, Arguments));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,6 +149,7 @@ public:
|
|||||||
void CancelEventTimers(const std::string& EventName, TLuaStateId StateId);
|
void CancelEventTimers(const std::string& EventName, TLuaStateId StateId);
|
||||||
sol::state_view GetStateForPlugin(const fs::path& PluginPath);
|
sol::state_view GetStateForPlugin(const fs::path& PluginPath);
|
||||||
TLuaStateId GetStateIDForPlugin(const fs::path& PluginPath);
|
TLuaStateId GetStateIDForPlugin(const fs::path& PluginPath);
|
||||||
|
void AddResultToCheck(const std::shared_ptr<TLuaResult>& Result);
|
||||||
|
|
||||||
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
||||||
|
|
||||||
|
|||||||
+23
-17
@@ -99,25 +99,31 @@ void Application::CheckForUpdates() {
|
|||||||
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Starting);
|
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Starting);
|
||||||
// checks current version against latest version
|
// checks current version against latest version
|
||||||
std::regex VersionRegex { R"(\d+\.\d+\.\d+\n*)" };
|
std::regex VersionRegex { R"(\d+\.\d+\.\d+\n*)" };
|
||||||
auto Response = Http::GET(GetBackendHostname(), 443, "/v/s");
|
for (const auto& url : GetBackendUrlsInOrder()) {
|
||||||
bool Matches = std::regex_match(Response, VersionRegex);
|
auto Response = Http::GET(GetBackendUrlsInOrder().at(0), 443, "/v/s");
|
||||||
if (Matches) {
|
bool Matches = std::regex_match(Response, VersionRegex);
|
||||||
auto MyVersion = ServerVersion();
|
if (Matches) {
|
||||||
auto RemoteVersion = Version(VersionStrToInts(Response));
|
auto MyVersion = ServerVersion();
|
||||||
if (IsOutdated(MyVersion, RemoteVersion)) {
|
auto RemoteVersion = Version(VersionStrToInts(Response));
|
||||||
std::string RealVersionString = RemoteVersion.AsString();
|
if (IsOutdated(MyVersion, RemoteVersion)) {
|
||||||
beammp_warn(std::string(ANSI_YELLOW_BOLD) + "NEW VERSION OUT! There's a new version (v" + RealVersionString + ") of the BeamMP-Server available! For more info visit https://wiki.beammp.com/en/home/server-maintenance#updating-the-server." + std::string(ANSI_RESET));
|
std::string RealVersionString = RemoteVersion.AsString();
|
||||||
|
beammp_warn(std::string(ANSI_YELLOW_BOLD) + "NEW VERSION OUT! There's a new version (v" + RealVersionString + ") of the BeamMP-Server available! For more info visit https://wiki.beammp.com/en/home/server-maintenance#updating-the-server." + std::string(ANSI_RESET));
|
||||||
|
} else {
|
||||||
|
beammp_info("Server up-to-date!");
|
||||||
|
}
|
||||||
|
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Good);
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
beammp_info("Server up-to-date!");
|
beammp_debug("Failed to fetch version from: " + url);
|
||||||
|
beammp_trace("got " + Response);
|
||||||
|
auto Lock = Sentry.CreateExclusiveContext();
|
||||||
|
Sentry.SetContext("get-response", { { "response", Response } });
|
||||||
|
Sentry.LogError("failed to get server version", _file_basename, _line);
|
||||||
|
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Bad);
|
||||||
}
|
}
|
||||||
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Good);
|
}
|
||||||
} else {
|
if (Application::GetSubsystemStatuses().at("UpdateCheck") == Application::Status::Bad) {
|
||||||
beammp_warn("Unable to fetch version from backend.");
|
beammp_warn("Unable to fetch version info from backend.");
|
||||||
beammp_trace("got " + Response);
|
|
||||||
auto Lock = Sentry.CreateExclusiveContext();
|
|
||||||
Sentry.SetContext("get-response", { { "response", Response } });
|
|
||||||
Sentry.LogError("failed to get server version", _file_basename, _line);
|
|
||||||
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Bad);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -4,6 +4,7 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "CustomAssert.h"
|
#include "CustomAssert.h"
|
||||||
#include "LuaAPI.h"
|
#include "LuaAPI.h"
|
||||||
|
#include "httplib.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <random>
|
#include <random>
|
||||||
@@ -33,17 +34,20 @@ std::string Http::GET(const std::string& host, int port, const std::string& targ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Http::POST(const std::string& host, int port, const std::string& target, const std::string& body, const std::string& ContentType, unsigned int* status) {
|
std::string Http::POST(const std::string& host, int port, const std::string& target, const std::string& body, const std::string& ContentType, unsigned int* status, const httplib::Headers& headers) {
|
||||||
httplib::SSLClient client(host, port);
|
httplib::SSLClient client(host, port);
|
||||||
|
client.set_read_timeout(std::chrono::seconds(10));
|
||||||
|
beammp_assert(client.is_valid());
|
||||||
client.enable_server_certificate_verification(false);
|
client.enable_server_certificate_verification(false);
|
||||||
client.set_address_family(AF_INET);
|
client.set_address_family(AF_INET);
|
||||||
auto res = client.Post(target.c_str(), body.c_str(), body.size(), ContentType.c_str());
|
auto res = client.Post(target.c_str(), headers, body.c_str(), body.size(), ContentType.c_str());
|
||||||
if (res) {
|
if (res) {
|
||||||
if (status) {
|
if (status) {
|
||||||
*status = res->status;
|
*status = res->status;
|
||||||
}
|
}
|
||||||
return res->body;
|
return res->body;
|
||||||
} else {
|
} else {
|
||||||
|
beammp_debug("POST failed: " + httplib::to_string(res.error()));
|
||||||
return Http::ErrorString;
|
return Http::ErrorString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-5
@@ -369,10 +369,6 @@ TConsole::TConsole() {
|
|||||||
mCommandline.set_history_limit(20);
|
mCommandline.set_history_limit(20);
|
||||||
mCommandline.set_prompt("> ");
|
mCommandline.set_prompt("> ");
|
||||||
BackupOldLog();
|
BackupOldLog();
|
||||||
bool success = mCommandline.enable_write_to_file("Server.log");
|
|
||||||
if (!success) {
|
|
||||||
beammp_error("unable to open file for writing: \"Server.log\"");
|
|
||||||
}
|
|
||||||
mCommandline.on_command = [this](Commandline& c) {
|
mCommandline.on_command = [this](Commandline& c) {
|
||||||
try {
|
try {
|
||||||
auto cmd = c.get_command();
|
auto cmd = c.get_command();
|
||||||
@@ -386,7 +382,7 @@ TConsole::TConsole() {
|
|||||||
} else {
|
} else {
|
||||||
auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(cmd), "", "" });
|
auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(cmd), "", "" });
|
||||||
while (!Future->Ready) {
|
while (!Future->Ready) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // TODO: Add a timeout
|
std::this_thread::yield(); // TODO: Add a timeout
|
||||||
}
|
}
|
||||||
if (Future->Error) {
|
if (Future->Error) {
|
||||||
beammp_lua_error(Future->ErrorMessage);
|
beammp_lua_error(Future->ErrorMessage);
|
||||||
|
|||||||
+59
-26
@@ -54,43 +54,76 @@ void THeartbeatThread::operator()() {
|
|||||||
|
|
||||||
auto Target = "/heartbeat";
|
auto Target = "/heartbeat";
|
||||||
unsigned int ResponseCode = 0;
|
unsigned int ResponseCode = 0;
|
||||||
T = Http::POST(Application::GetBackendHostname(), 443, Target, Body, "application/x-www-form-urlencoded", &ResponseCode);
|
|
||||||
|
|
||||||
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
|
json::Document Doc;
|
||||||
beammp_trace("got " + T + " from backend");
|
bool Ok = false;
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Bad);
|
for (const auto& Url : Application::GetBackendUrlsInOrder()) {
|
||||||
SentryReportError(Application::GetBackendHostname() + Target, ResponseCode);
|
T = Http::POST(Url, 443, Target, Body, "application/x-www-form-urlencoded", &ResponseCode, { { "api-v", "2" } });
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
beammp_trace(T);
|
||||||
T = Http::POST(Application::GetBackup1Hostname(), 443, Target, Body, "application/x-www-form-urlencoded", &ResponseCode);
|
Doc.Parse(T.data(), T.size());
|
||||||
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
|
if (Doc.HasParseError() || !Doc.IsObject()) {
|
||||||
SentryReportError(Application::GetBackup1Hostname() + Target, ResponseCode);
|
beammp_error("Backend response failed to parse as valid json");
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Bad);
|
beammp_debug("Response was: `" + T + "`");
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
Sentry.SetContext("JSON Response", { { "reponse", T } });
|
||||||
T = Http::POST(Application::GetBackup2Hostname(), 443, Target, Body, "application/x-www-form-urlencoded", &ResponseCode);
|
SentryReportError(Url + Target, ResponseCode);
|
||||||
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
|
} else if (ResponseCode != 200) {
|
||||||
beammp_warn("Backend system refused server! Server will not show in the public server list.");
|
SentryReportError(Url + Target, ResponseCode);
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Bad);
|
|
||||||
isAuth = false;
|
|
||||||
SentryReportError(Application::GetBackup2Hostname() + Target, ResponseCode);
|
|
||||||
} else {
|
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
// all ok
|
||||||
|
Ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
}
|
||||||
|
std::string Status {};
|
||||||
|
std::string Code {};
|
||||||
|
std::string Message {};
|
||||||
|
const auto StatusKey = "status";
|
||||||
|
const auto CodeKey = "code";
|
||||||
|
const auto MessageKey = "msg";
|
||||||
|
|
||||||
|
if (Ok) {
|
||||||
|
if (Doc.HasMember(StatusKey) && Doc[StatusKey].IsString()) {
|
||||||
|
Status = Doc[StatusKey].GetString();
|
||||||
|
} else {
|
||||||
|
Sentry.SetContext("JSON Response", { { StatusKey, "invalid string / missing" } });
|
||||||
|
Ok = false;
|
||||||
|
}
|
||||||
|
if (Doc.HasMember(CodeKey) && Doc[CodeKey].IsString()) {
|
||||||
|
Code = Doc[CodeKey].GetString();
|
||||||
|
} else {
|
||||||
|
Sentry.SetContext("JSON Response", { { CodeKey, "invalid string / missing" } });
|
||||||
|
Ok = false;
|
||||||
|
}
|
||||||
|
if (Doc.HasMember(MessageKey) && Doc[MessageKey].IsString()) {
|
||||||
|
Message = Doc[MessageKey].GetString();
|
||||||
|
} else {
|
||||||
|
Sentry.SetContext("JSON Response", { { MessageKey, "invalid string / missing" } });
|
||||||
|
Ok = false;
|
||||||
|
}
|
||||||
|
if (!Ok) {
|
||||||
|
beammp_error("Missing/invalid json members in backend response");
|
||||||
|
Sentry.LogError("Missing/invalid json members in backend response", __FILE__, std::to_string(__LINE__));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAuth) {
|
if (Ok && !isAuth) {
|
||||||
if (T == "2000") {
|
if (Status == "2000") {
|
||||||
beammp_info(("Authenticated!"));
|
beammp_info(("Authenticated!"));
|
||||||
isAuth = true;
|
isAuth = true;
|
||||||
} else if (T == "200") {
|
} else if (Status == "200") {
|
||||||
beammp_info(("Resumed authenticated session!"));
|
beammp_info(("Resumed authenticated session!"));
|
||||||
isAuth = true;
|
isAuth = true;
|
||||||
|
} else {
|
||||||
|
if (Message.empty()) {
|
||||||
|
Message = "Backend didn't provide a reason";
|
||||||
|
}
|
||||||
|
beammp_error("Backend REFUSED the auth key. " + Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAuth) {
|
||||||
|
Application::SetSubsystemStatus("Heartbeat", Application::Status::Good);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-20
@@ -54,25 +54,17 @@ void TLuaEngine::operator()() {
|
|||||||
auto ResultCheckThread = std::thread([&] {
|
auto ResultCheckThread = std::thread([&] {
|
||||||
RegisterThread("ResultCheckThread");
|
RegisterThread("ResultCheckThread");
|
||||||
while (!mShutdown) {
|
while (!mShutdown) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
std::unique_lock Lock(mResultsToCheckMutex);
|
std::unique_lock Lock(mResultsToCheckMutex);
|
||||||
if (!mResultsToCheck.empty()) {
|
if (!mResultsToCheck.empty()) {
|
||||||
auto Res = mResultsToCheck.front();
|
auto Res = mResultsToCheck.front();
|
||||||
mResultsToCheck.pop();
|
mResultsToCheck.pop();
|
||||||
Lock.unlock();
|
Lock.unlock();
|
||||||
|
|
||||||
size_t Waited = 0;
|
if (!Res->Ready) {
|
||||||
while (!Res->Ready) {
|
Lock.lock();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
mResultsToCheck.push(Res);
|
||||||
Waited++;
|
Lock.unlock();
|
||||||
if (Waited > 250) {
|
|
||||||
// FIXME: This should *eventually* timeout.
|
|
||||||
// beammp_lua_error(Res->Function + " in " + Res->StateId + " took >1s to respond, not printing possible errors");
|
|
||||||
Lock.lock();
|
|
||||||
mResultsToCheck.push(Res);
|
|
||||||
Lock.unlock();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Res->Error) {
|
if (Res->Error) {
|
||||||
if (Res->ErrorMessage != BeamMPFnNotFoundError) {
|
if (Res->ErrorMessage != BeamMPFnNotFoundError) {
|
||||||
@@ -80,13 +72,14 @@ void TLuaEngine::operator()() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// event loop
|
// event loop
|
||||||
auto Before = std::chrono::high_resolution_clock::now();
|
auto Before = std::chrono::high_resolution_clock::now();
|
||||||
while (!mShutdown) {
|
while (!mShutdown) {
|
||||||
if (mLuaStates.size() == 0) {
|
if (mLuaStates.size() == 0) {
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(500));
|
std::this_thread::sleep_for(std::chrono::seconds(100));
|
||||||
}
|
}
|
||||||
{ // Timed Events Scope
|
{ // Timed Events Scope
|
||||||
std::unique_lock Lock(mTimedEventsMutex);
|
std::unique_lock Lock(mTimedEventsMutex);
|
||||||
@@ -149,6 +142,11 @@ TLuaStateId TLuaEngine::GetStateIDForPlugin(const fs::path& PluginPath) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TLuaEngine::AddResultToCheck(const std::shared_ptr<TLuaResult>& Result) {
|
||||||
|
std::unique_lock Lock(mResultsToCheckMutex);
|
||||||
|
mResultsToCheck.push(Result);
|
||||||
|
}
|
||||||
|
|
||||||
void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results, const std::optional<std::chrono::high_resolution_clock::duration>& Max) {
|
void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results, const std::optional<std::chrono::high_resolution_clock::duration>& Max) {
|
||||||
for (const auto& Result : Results) {
|
for (const auto& Result : Results) {
|
||||||
bool Cancelled = false;
|
bool Cancelled = false;
|
||||||
@@ -705,6 +703,7 @@ void TLuaEngine::StateThreadData::AddPath(const fs::path& Path) {
|
|||||||
|
|
||||||
void TLuaResult::WaitUntilReady() {
|
void TLuaResult::WaitUntilReady() {
|
||||||
while (!Ready) {
|
while (!Ready) {
|
||||||
|
std::this_thread::yield();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,12 +761,7 @@ void TPluginMonitor::operator()() {
|
|||||||
auto StateID = mEngine.GetStateIDForPlugin(fs::path(Pair.first).parent_path());
|
auto StateID = mEngine.GetStateIDForPlugin(fs::path(Pair.first).parent_path());
|
||||||
auto Res = mEngine.EnqueueScript(StateID, Chunk);
|
auto Res = mEngine.EnqueueScript(StateID, Chunk);
|
||||||
// TODO: call onInit
|
// TODO: call onInit
|
||||||
while (!Res->Ready) {
|
mEngine.AddResultToCheck(Res);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
}
|
|
||||||
if (Res->Error) {
|
|
||||||
beammp_lua_error(Res->ErrorMessage);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: trigger onFileChanged event
|
// TODO: trigger onFileChanged event
|
||||||
beammp_trace("Change detected in file \"" + Pair.first + "\", event trigger not implemented yet");
|
beammp_trace("Change detected in file \"" + Pair.first + "\", event trigger not implemented yet");
|
||||||
|
|||||||
@@ -187,7 +187,11 @@ void TNetwork::Identify(const TConnection& client) {
|
|||||||
} else if (Code == 'D') {
|
} else if (Code == 'D') {
|
||||||
HandleDownload(client.Socket);
|
HandleDownload(client.Socket);
|
||||||
} else if (Code == 'P') {
|
} else if (Code == 'P') {
|
||||||
|
#if defined(BEAMMP_LINUX) || defined(BEAMMP_APPLE)
|
||||||
|
send(client.Socket, "P", 1, MSG_NOSIGNAL);
|
||||||
|
#else
|
||||||
send(client.Socket, "P", 1, 0);
|
send(client.Socket, "P", 1, 0);
|
||||||
|
#endif
|
||||||
CloseSocketProper(client.Socket);
|
CloseSocketProper(client.Socket);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@@ -778,7 +782,11 @@ void TNetwork::SplitLoad(TClient& c, size_t Sent, size_t Size, bool D, const std
|
|||||||
bool TNetwork::TCPSendRaw(TClient& C, SOCKET socket, char* Data, int32_t Size) {
|
bool TNetwork::TCPSendRaw(TClient& C, SOCKET socket, char* Data, int32_t Size) {
|
||||||
intmax_t Sent = 0;
|
intmax_t Sent = 0;
|
||||||
do {
|
do {
|
||||||
|
#if defined(BEAMMP_LINUX) || defined(BEAMMP_APPLE)
|
||||||
|
intmax_t Temp = send(socket, &Data[Sent], int(Size - Sent), MSG_NOSIGNAL);
|
||||||
|
#else
|
||||||
intmax_t Temp = send(socket, &Data[Sent], int(Size - Sent), 0);
|
intmax_t Temp = send(socket, &Data[Sent], int(Size - Sent), 0);
|
||||||
|
#endif
|
||||||
if (Temp < 1) {
|
if (Temp < 1) {
|
||||||
beammp_info("Socket Closed! " + std::to_string(socket));
|
beammp_info("Socket Closed! " + std::to_string(socket));
|
||||||
CloseSocketProper(socket);
|
CloseSocketProper(socket);
|
||||||
|
|||||||
+2
-2
@@ -21,8 +21,8 @@ TPPSMonitor::TPPSMonitor(TServer& Server)
|
|||||||
void TPPSMonitor::operator()() {
|
void TPPSMonitor::operator()() {
|
||||||
RegisterThread("PPSMonitor");
|
RegisterThread("PPSMonitor");
|
||||||
while (!mNetwork) {
|
while (!mNetwork) {
|
||||||
// hard spi
|
// hard(-ish) spin
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
beammp_debug("PPSMonitor starting");
|
beammp_debug("PPSMonitor starting");
|
||||||
Application::SetSubsystemStatus("PPSMonitor", Application::Status::Good);
|
Application::SetSubsystemStatus("PPSMonitor", Application::Status::Good);
|
||||||
|
|||||||
+14
-16
@@ -7,14 +7,14 @@
|
|||||||
#include <any>
|
#include <any>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "LuaAPI.h"
|
#include "LuaAPI.h"
|
||||||
|
|
||||||
#undef GetObject // Fixes Windows
|
#undef GetObject // Fixes Windows
|
||||||
|
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
|
|
||||||
namespace json = rapidjson;
|
|
||||||
|
|
||||||
TServer::TServer(const std::vector<std::string_view>& Arguments) {
|
TServer::TServer(const std::vector<std::string_view>& Arguments) {
|
||||||
beammp_info("BeamMP Server v" + Application::ServerVersionString());
|
beammp_info("BeamMP Server v" + Application::ServerVersionString());
|
||||||
Application::SetSubsystemStatus("Server", Application::Status::Starting);
|
Application::SetSubsystemStatus("Server", Application::Status::Starting);
|
||||||
@@ -171,27 +171,25 @@ void TServer::HandleEvent(TClient& c, const std::string& Data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TServer::IsUnicycle(TClient& c, const std::string& CarJson) {
|
bool TServer::IsUnicycle(TClient& c, const std::string& CarJson) {
|
||||||
rapidjson::Document Car;
|
try {
|
||||||
Car.Parse(CarJson.c_str(), CarJson.size());
|
auto Car = nlohmann::json::parse(CarJson);
|
||||||
if (Car.HasParseError()) {
|
const std::string jbm = "jbm";
|
||||||
beammp_error("Failed to parse vehicle data -> " + CarJson);
|
if (Car.contains(jbm) && Car[jbm].is_string() && Car[jbm] == "unicycle") {
|
||||||
} else if (Car["jbm"].IsString() && std::string(Car["jbm"].GetString()) == "unicycle") {
|
return true;
|
||||||
return true;
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
beammp_error("Failed to parse vehicle data as json for client " + std::to_string(c.GetID()) + ": '" + CarJson + "'");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TServer::ShouldSpawn(TClient& c, const std::string& CarJson, int ID) {
|
bool TServer::ShouldSpawn(TClient& c, const std::string& CarJson, int ID) {
|
||||||
|
if (IsUnicycle(c, CarJson) && c.GetUnicycleID() < 0) {
|
||||||
if (c.GetUnicycleID() > -1 && (c.GetCarCount() - 1) < Application::Settings.MaxCars) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsUnicycle(c, CarJson)) {
|
|
||||||
c.SetUnicycleID(ID);
|
c.SetUnicycleID(ID);
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return c.GetCarCount() < Application::Settings.MaxCars;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Application::Settings.MaxCars > c.GetCarCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network) {
|
void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network) {
|
||||||
|
|||||||
+8
-4
@@ -78,10 +78,6 @@ int main(int argc, char** argv) {
|
|||||||
int BeamMPServerMain(MainArguments Arguments) {
|
int BeamMPServerMain(MainArguments Arguments) {
|
||||||
setlocale(LC_ALL, "C");
|
setlocale(LC_ALL, "C");
|
||||||
Application::InitializeConsole();
|
Application::InitializeConsole();
|
||||||
Application::SetSubsystemStatus("Main", Application::Status::Starting);
|
|
||||||
|
|
||||||
SetupSignalHandlers();
|
|
||||||
|
|
||||||
ArgsParser Parser;
|
ArgsParser Parser;
|
||||||
Parser.RegisterArgument({ "help" }, ArgsParser::NONE);
|
Parser.RegisterArgument({ "help" }, ArgsParser::NONE);
|
||||||
Parser.RegisterArgument({ "version" }, ArgsParser::NONE);
|
Parser.RegisterArgument({ "version" }, ArgsParser::NONE);
|
||||||
@@ -122,6 +118,14 @@ int BeamMPServerMain(MainArguments Arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application::SetSubsystemStatus("Main", Application::Status::Starting);
|
||||||
|
bool Success = Application::Console().Internal().enable_write_to_file("Server.log");
|
||||||
|
if (!Success) {
|
||||||
|
beammp_error("unable to open file for writing: \"Server.log\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupSignalHandlers();
|
||||||
|
|
||||||
bool Shutdown = false;
|
bool Shutdown = false;
|
||||||
Application::RegisterShutdownHandler([&Shutdown] {
|
Application::RegisterShutdownHandler([&Shutdown] {
|
||||||
Application::SetSubsystemStatus("Main", Application::Status::ShuttingDown);
|
Application::SetSubsystemStatus("Main", Application::Status::ShuttingDown);
|
||||||
|
|||||||
Reference in New Issue
Block a user