Compare commits

...

22 Commits

Author SHA1 Message Date
Lion 39badf432d remove whitespace 2024-01-17 13:15:30 +01:00
Lion Kortlepel 03307e71fb use a beammp_lua_errorf instead of a std::terminate on sol2 assertion failure 2023-12-05 18:25:27 +01:00
Lion 872c2d410d New buildsystem (#197) 2023-12-05 18:21:20 +01:00
Lion Kortlepel f98704e0f3 fix warnings about implicit conversion 2023-12-05 18:05:35 +01:00
Lion Kortlepel dea203c108 make IThreaded::~IThreaded virtual to make destruction happen 2023-12-05 18:03:13 +01:00
Lion Kortlepel e245c9e9e2 fix pps monitor warning about virtual dtor 2023-12-05 18:02:35 +01:00
Lion Kortlepel 11fe5ad200 fix invalid timeout value 2023-12-05 18:00:34 +01:00
Lion Kortlepel 667da22b0e Merge remote-tracking branch 'origin/master' into new-buildsystem 2023-12-05 17:59:05 +01:00
Lion Kortlepel a6eb2f7bfe switch to vcpkg+cmake, add debian build to workflows
using lionkor's template (MIT licensed)

This is a combination of 64 commits.
2023-12-05 17:57:19 +01:00
Lion 2c29a195f9 optimize: Add conditional variable to LuaResult (#162)
Implementing TODO for optimization I saw in the code.
2023-03-27 13:31:21 +02:00
rgnter 222d2492ff Merge branch 'master' into optimize/add_cv_to_luaresult 2023-03-21 20:17:17 +01:00
Simon 879b9772f5 Apply suggestions from code review
Co-authored-by: Lion <development@kortlepel.com>
2023-01-15 17:12:35 +00:00
Anonymous275 c51cf090ef fix linux build 2023-01-15 17:12:35 +00:00
Anonymous275 d677d8d58d rename Hash function to HashPassword
move HashPassword to cpp only
move check to line 285
2023-01-15 17:12:35 +00:00
Anonymous275 4b30918659 - add 120 seconds timeout 2023-01-15 17:12:35 +00:00
Anonymous275 688e46f524 - fix linux build 2023-01-15 17:12:35 +00:00
Anonymous275 9f59c27b1f - add hash function
- add password config
- add debug messages for password stages
- add pass boolean for heartbeat
- adjust network codes
2023-01-15 17:12:35 +00:00
Lion 6a11bcd20b fix bad package name for Ubuntu in Readme (#161)
The package name for liblua required to build is not correct. The
correct name is
[`liblua-5.3-dev`](https://packages.ubuntu.com/search?suite=all&searchon=names&keywords=liblua5.3)
2022-12-21 16:29:49 +01:00
rgnter b7b578bf3e add conditional variable to LuaResult 2022-12-18 14:45:33 +01:00
rgnter 6c145a6dbf fix: Bad package name for Ubuntu 2022-12-18 12:32:45 +01:00
Lion 67d792e0e0 remove repeated dependency from README (#155) 2022-11-14 14:32:19 +01:00
Qest333 eaeef0c7d0 Remove double dependency from README 2022-11-14 14:00:21 +01:00
62 changed files with 957 additions and 778 deletions
-78
View File
@@ -1,78 +0,0 @@
name: CMake Linux Build
on: [push]
env:
BUILD_TYPE: Release
jobs:
linux-build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- name: Install Dependencies
env:
beammp_sentry_url: ${{ secrets.BEAMMP_SECRET_SENTRY_URL }}
run: |
echo ${#beammp_sentry_url}
sudo apt-get update
sudo apt-get install -y libz-dev rapidjson-dev liblua5.3 libssl-dev libwebsocketpp-dev libcurl4-openssl-dev cmake g++-10 libboost1.74-all-dev
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build-linux
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build-linux
env:
beammp_sentry_url: ${{ secrets.BEAMMP_SECRET_SENTRY_URL }}
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=g++-10 -DBEAMMP_SECRET_SENTRY_URL="$beammp_sentry_url"
- name: Build Server
working-directory: ${{github.workspace}}/build-linux
shell: bash
run: cmake --build . --config $BUILD_TYPE -t BeamMP-Server --parallel
- name: Build Tests
working-directory: ${{github.workspace}}/build-linux
shell: bash
run: cmake --build . --config $BUILD_TYPE -t BeamMP-Server-tests --parallel
- name: Archive server artifact
uses: actions/upload-artifact@v2
with:
name: BeamMP-Server-linux
path: ${{github.workspace}}/build-linux/BeamMP-Server
- name: Archive test artifact
uses: actions/upload-artifact@v2
with:
name: BeamMP-Server-linux-tests
path: ${{github.workspace}}/build-linux/BeamMP-Server-tests
run-tests:
needs: linux-build
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@master
with:
name: BeamMP-Server-linux-tests
path: ${{github.workspace}}
- name: Install Runtime Dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y liblua5.3-0 libssl3 curl
- name: Test
working-directory: ${{github.workspace}}
shell: bash
run: |
chmod +x ./BeamMP-Server-tests
./BeamMP-Server-tests
-58
View File
@@ -1,58 +0,0 @@
name: CMake Windows Build
on: [push]
env:
BUILD_TYPE: Release
jobs:
windows-build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Restore artifacts, or run vcpkg, build and cache artifacts
uses: lukka/run-vcpkg@v7
id: runvcpkg
with:
vcpkgArguments: 'lua zlib rapidjson openssl websocketpp curl'
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
vcpkgGitCommitId: "16ee2ecb31788c336ace8bb14c21801efb6836e4"
vcpkgTriplet: 'x64-windows-static'
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build-windows
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build-windows
env:
beammp_sentry_url: ${{ secrets.BEAMMP_SECRET_SENTRY_URL }}
run: cmake $GITHUB_WORKSPACE -DSENTRY_BACKEND=breakpad -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake' -DVCPKG_TARGET_TRIPLET=x64-windows-static -DBEAMMP_SECRET_SENTRY_URL="$beammp_sentry_url"
- name: Build
working-directory: ${{github.workspace}}/build-windows
shell: bash
run: cmake --build . --config $BUILD_TYPE
- name: Archive artifacts
uses: actions/upload-artifact@v2
with:
name: 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
+150
View File
@@ -0,0 +1,150 @@
name: Linux
on: [push]
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
jobs:
debian-11-build:
runs-on: ubuntu-latest
container:
image: debian:11
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install git
run: |
apt-get update -y
apt-get install -y git
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Git config safe directory
shell: bash
run: bash ./scripts/debian-11/1.5-git-safe.sh
- name: Install Dependencies
run: bash ./scripts/debian-11/1-install-deps.sh
- name: Create Build Environment
run: bash ./scripts/debian-11/2-configure.sh '-DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake'
- name: Build Server
run: bash ./scripts/debian-11/3-build.sh
- name: Archive server artifact
uses: actions/upload-artifact@v2
with:
name: BeamMP-Server-debian
path: ./bin/BeamMP-Server
- 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
ubuntu-22-04-build:
runs-on: ubuntu-latest
container:
image: ubuntu:22.04
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install git
run: |
apt-get update -y
apt-get install -y git
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Git config safe directory
shell: bash
run: bash ./scripts/ubuntu-22.04/1.5-git-safe.sh
- name: Install Dependencies
run: bash ./scripts/ubuntu-22.04/1-install-deps.sh
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
with:
runVcpkgInstall: true
- name: Create Build Environment
run: bash ./scripts/ubuntu-22.04/2-configure.sh '-DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake'
- name: Build Server
run: bash ./scripts/ubuntu-22.04/3-build.sh
- name: Archive server artifact
uses: actions/upload-artifact@v2
with:
name: BeamMP-Server-ubuntu
path: ./bin/BeamMP-Server
- 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
- 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
-115
View File
@@ -1,115 +0,0 @@
name: Release Create & Build
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
env:
BUILD_TYPE: Release
jobs:
create-release:
runs-on: ubuntu-latest
name: Create Release
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: true
body: |
Files included in this release:
- `BeamMP-Server.exe` is the windows build
- `BeamMP-Server-linux` is a ubuntu build, so you need the dependencies listed in README.md to run it. For any other distros please build from source as described in README.md.
upload-release-files-linux:
name: Upload Linux Release Files
runs-on: ubuntu-22.04
needs: create-release
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libz-dev rapidjson-dev liblua5.3 libssl-dev libwebsocketpp-dev libcurl4-openssl-dev libboost-dev libboost1.74-all-dev libboost1.74-dev
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build-linux
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build-linux
env:
beammp_sentry_url: ${{ secrets.BEAMMP_SECRET_SENTRY_URL }}
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=g++-10 -DBEAMMP_SECRET_SENTRY_URL="$beammp_sentry_url"
- name: Build
working-directory: ${{github.workspace}}/build-linux
shell: bash
run: cmake --build . --config $BUILD_TYPE
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ${{github.workspace}}/build-linux/BeamMP-Server
asset_name: BeamMP-Server-linux
asset_content_type: application/x-elf
upload-release-files-windows:
name: Upload Windows Release Files
runs-on: windows-latest
needs: create-release
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Restore artifacts, or run vcpkg, build and cache artifacts
uses: lukka/run-vcpkg@v7
id: runvcpkg
with:
vcpkgArguments: 'lua zlib rapidjson openssl websocketpp curl'
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
vcpkgGitCommitId: '16ee2ecb31788c336ace8bb14c21801efb6836e4'
vcpkgTriplet: 'x64-windows-static'
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build-windows
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build-windows
env:
beammp_sentry_url: ${{ secrets.BEAMMP_SECRET_SENTRY_URL }}
run: cmake $GITHUB_WORKSPACE -DSENTRY_BACKEND=breakpad -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake' -DVCPKG_TARGET_TRIPLET=x64-windows-static -DBEAMMP_SECRET_SENTRY_URL="$beammp_sentry_url"
- name: Build
working-directory: ${{github.workspace}}/build-windows
shell: bash
run: cmake --build . --config $BUILD_TYPE
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ${{github.workspace}}/build-windows/Release/BeamMP-Server.exe
asset_name: BeamMP-Server.exe
asset_content_type: application/vnd.microsoft.portable-executable
+168
View File
@@ -0,0 +1,168 @@
name: Release Create & Build
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
jobs:
create-release:
runs-on: ubuntu-latest
name: Create Release
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: true
body: |
Files included in this release:
- `BeamMP-Server.exe` is the windows build.
- `BeamMP-Server-debian` is a Debian 11 build, requires `liblua5.3-0`.
- `BeamMP-Server-ubuntu` is a Ubuntu 22.04 build, requires `liblua5.3-0`.
upload-release-files-debian-11:
name: Build and upload Debian 11 Release Files
runs-on: ubuntu-22.04
needs: create-release
container:
image: debian:11
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install git
run: |
apt-get update -y
apt-get install -y git
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Git config safe directory
shell: bash
run: bash ./scripts/debian-11/1.5-git-safe.sh
- name: Install Dependencies
run: bash ./scripts/debian-11/1-install-deps.sh
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
with:
runVcpkgInstall: true
- name: Create Build Environment
run: bash ./scripts/debian-11/2-configure.sh '-DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake'
- name: Build Server
run: bash ./scripts/debian-11/3-build.sh
- name: Upload Release Asset
id: upload-release-asset
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
asset_name: BeamMP-Server-debian
asset_content_type: application/x-elf
upload-release-files-ubuntu-22-04:
name: Build and upload Ubuntu 22.04 Release Files
runs-on: ubuntu-22.04
needs: create-release
container:
image: ubuntu:22.04
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install git
run: |
apt-get update -y
apt-get install -y git
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Git config safe directory
shell: bash
run: bash ./scripts/ubuntu-22.04/1.5-git-safe.sh
- name: Install Dependencies
run: bash ./scripts/ubuntu-22.04/1-install-deps.sh
- name: Create Build Environment
run: bash ./scripts/ubuntu-22.04/2-configure.sh '-DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake'
- name: Build Server
run: bash ./scripts/ubuntu-22.04/3-build.sh
- name: Upload Release Asset
id: upload-release-asset
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
asset_name: BeamMP-Server-ubuntu
asset_content_type: application/x-elf
upload-release-files-windows:
name: Build and upload Windows Release Files
runs-on: windows-latest
needs: create-release
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Create Build Environment
shell: bash
run: ./scripts/windows/1-configure.sh
- name: Build Server
shell: bash
run: bash ./scripts/windows/2-build.sh
- name: Upload Release Asset
id: upload-release-asset
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.exe
asset_name: BeamMP-Server.exe
asset_content_type: application/vnd.microsoft.portable-executable
+42
View File
@@ -0,0 +1,42 @@
name: Windows
on: [push]
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
jobs:
windows-build:
runs-on: windows-latest
steps:
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
with:
runVcpkgInstall: true
- name: Create Build Environment
shell: bash
run: ./scripts/windows/1-configure.sh
- name: Build Server
shell: bash
run: bash ./scripts/windows/2-build.sh
- name: Archive server artifact
uses: actions/upload-artifact@v2
with:
name: BeamMP-Server-windows
path: ./bin/BeamMP-Server.exe
+3 -30
View File
@@ -1,33 +1,6 @@
[submodule "deps/commandline"] [submodule "deps/commandline"]
path = deps/commandline path = deps/commandline
url = https://github.com/lionkor/commandline url = https://github.com/lionkor/commandline
[submodule "deps/asio"] [submodule "vcpkg"]
path = deps/asio path = vcpkg
url = https://github.com/chriskohlhoff/asio url = https://github.com/Microsoft/vcpkg.git
[submodule "deps/rapidjson"]
path = deps/rapidjson
url = https://github.com/Tencent/rapidjson
[submodule "deps/toml11"]
path = deps/toml11
url = https://github.com/ToruNiina/toml11
[submodule "deps/sentry-native"]
path = deps/sentry-native
url = https://github.com/getsentry/sentry-native
[submodule "deps/sol2"]
path = deps/sol2
url = https://github.com/ThePhD/sol2
[submodule "deps/libzip"]
path = deps/libzip
url = https://github.com/nih-at/libzip
[submodule "deps/cpp-httplib"]
path = deps/cpp-httplib
url = https://github.com/yhirose/cpp-httplib
[submodule "deps/json"]
path = deps/json
url = https://github.com/nlohmann/json
[submodule "deps/fmt"]
path = deps/fmt
url = https://github.com/fmtlib/fmt
[submodule "deps/doctest"]
path = deps/doctest
url = https://github.com/doctest/doctest
+185 -235
View File
@@ -1,262 +1,212 @@
# 3.4 is required for imported targets. cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
message(STATUS "You can find build instructions and a list of dependencies in the README at \ if (WIN32)
https://github.com/BeamMP/BeamMP-Server") set(VCPKG_TARGET_TRIPLET x64-windows-static)
project(BeamMP-Server
DESCRIPTION "Server for BeamMP - The Multiplayer Mod for BeamNG.drive"
HOMEPAGE_URL https://beammp.com
LANGUAGES CXX C)
find_package(Git REQUIRED)
# Update submodules as needed
option(GIT_SUBMODULE "Check submodules during build" ON)
if(GIT_SUBMODULE)
message(STATUS "Submodule update")
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT)
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
endif()
endif() endif()
include(cmake/Vcpkg.cmake) # needs to happen before project()
set(HTTPLIB_REQUIRE_OPENSSL ON) project(
set(SENTRY_BUILD_SHARED_LIBS OFF) "BeamMP-Server" # replace this
VERSION 3.3.0
)
add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT=1) include(cmake/StandardSettings.cmake)
include(cmake/StaticAnalyzers.cmake)
include(cmake/Git.cmake)
option(WIN32_STATIC_RUNTIME "Build statically-linked runtime on windows (don't touch unless you know what you're doing)" ON) # below are options which should be changed
# ------------------------ APPLE --------------------------------- ### SETTINGS ###
if(APPLE)
if(IS_DIRECTORY /opt/homebrew/Cellar/lua@5.3/5.3.6)
set(LUA_INCLUDE_DIR /opt/homebrew/Cellar/lua@5.3/5.3.6/include/lua5.3)
link_directories(/opt/homebrew/Cellar/lua@5.3/5.3.6/lib)
else()
set(LUA_INCLUDE_DIR /usr/local/Cellar/lua@5.3/5.3.6/include/lua5.3)
link_directories(/usr/local/Cellar/lua@5.3/5.3.6/lib)
endif()
set(LUA_LIBRARIES lua)
if(IS_DIRECTORY /opt/homebrew/opt/openssl@1.1)
include_directories(/opt/homebrew/opt/openssl@1.1/include)
link_directories(/opt/homebrew/opt/openssl@1.1/lib)
else()
include_directories(/usr/local/opt/openssl@1.1/include)
link_directories(/usr/local/opt/openssl@1.1/lib)
endif()
# ------------------------ WINDOWS ---------------------------------
elseif (WIN32)
if (WIN32_STATIC_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
# ------------------------ UNIX ------------------------------------
elseif (UNIX)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
option(SANITIZE "Turns on thread and UB sanitizers" OFF)
if (SANITIZE)
message(STATUS "sanitize is ON")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize={address,thread,undefined}")
endif (SANITIZE)
endif ()
set(BUILD_SHARED_LIBS OFF) # add all headers (.h, .hpp) to this
# ------------------------ SENTRY --------------------------------- set(PRJ_HEADERS
message(STATUS "Checking for Sentry URL") include/ArgsParser.h
# 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()
set(SENTRY_BACKEND breakpad)
endif()
add_subdirectory("deps/sentry-native")
# ------------------------ C++ SETUP ---------------------------------
set(CMAKE_CXX_STANDARD 17)
# ------------------------ DEPENDENCIES ------------------------------
message(STATUS "Adding local source dependencies")
# this has to happen before -DDEBUG since it wont compile properly with -DDEBUG
add_subdirectory(deps)
# ------------------------ VARIABLES ---------------------------------
include(FindLua)
include(FindOpenSSL)
include(FindThreads)
include(FindZLIB)
find_package(Boost 1.70 REQUIRED COMPONENTS system)
set(BeamMP_Sources
include/TConsole.h src/TConsole.cpp
include/TServer.h src/TServer.cpp
include/Compat.h src/Compat.cpp
include/Common.h src/Common.cpp
include/Client.h src/Client.cpp
include/VehicleData.h src/VehicleData.cpp
include/TConfig.h src/TConfig.cpp
include/TLuaEngine.h src/TLuaEngine.cpp
include/TLuaPlugin.h src/TLuaPlugin.cpp
include/TResourceManager.h src/TResourceManager.cpp
include/THeartbeatThread.h src/THeartbeatThread.cpp
include/Http.h src/Http.cpp
include/TSentry.h src/TSentry.cpp
include/TPPSMonitor.h src/TPPSMonitor.cpp
include/TNetwork.h src/TNetwork.cpp
include/LuaAPI.h src/LuaAPI.cpp
include/TScopedTimer.h src/TScopedTimer.cpp
include/SignalHandling.h src/SignalHandling.cpp
include/ArgsParser.h src/ArgsParser.cpp
include/TPluginMonitor.h src/TPluginMonitor.cpp
include/Environment.h
include/BoostAliases.h include/BoostAliases.h
include/Client.h
include/Common.h
include/Compat.h
include/Cryptography.h
include/CustomAssert.h
include/Defer.h
include/Environment.h
include/Http.h
include/IThreaded.h
include/Json.h
include/LuaAPI.h
include/RWMutex.h
include/SignalHandling.h
include/TConfig.h
include/TConsole.h
include/THeartbeatThread.h
include/TLuaEngine.h
include/TLuaPlugin.h
include/TNetwork.h
include/TPluginMonitor.h
include/TPPSMonitor.h
include/TResourceManager.h
include/TScopedTimer.h
include/TServer.h
include/VehicleData.h
)
# add all source files (.cpp) to this, except the one with main()
set(PRJ_SOURCES
src/ArgsParser.cpp
src/Client.cpp
src/Common.cpp
src/Compat.cpp
src/Http.cpp
src/LuaAPI.cpp
src/SignalHandling.cpp
src/TConfig.cpp
src/TConsole.cpp
src/THeartbeatThread.cpp
src/TLuaEngine.cpp
src/TLuaPlugin.cpp
src/TNetwork.cpp
src/TPluginMonitor.cpp
src/TPPSMonitor.cpp
src/TResourceManager.cpp
src/TScopedTimer.cpp
src/TServer.cpp
src/VehicleData.cpp
) )
set(BeamMP_Includes find_package(Lua REQUIRED)
${LUA_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
"${CMAKE_CURRENT_SOURCE_DIR}/deps/cpp-httplib"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/commandline"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/json/single_include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/sol2/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/rapidjson/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps"
)
set(BeamMP_Definitions # set the source file containing main()
SECRET_SENTRY_URL="${BEAMMP_SECRET_SENTRY_URL}" set(PRJ_MAIN src/main.cpp)
) # set the source file containing the test's main
set(PRJ_TEST_MAIN test/test_main.cpp)
if (WIN32) # set include paths not part of libraries
list(APPEND BeamMP_Definitions _WIN32_WINNT=0x0601) set(PRJ_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
list(APPEND BeamMP_Definitions _CRT_SECURE_NO_WARNINGS) # set compile features (e.g. standard version)
endif() set(PRJ_COMPILE_FEATURES cxx_std_20)
if (UNIX) # set #defines (test enable/disable not included here)
set(BeamMP_CompileOptions set(PRJ_DEFINITIONS CPPHTTPLIB_OPENSSL_SUPPORT)
-Wall # add all libraries used by the project (WARNING: also set them in vcpkg.json!)
-Wextra set(PRJ_LIBRARIES
-Wpedantic
-Werror=uninitialized
-Werror=float-equal
-Werror=pointer-arith
-Werror=double-promotion
-Werror=write-strings
-Werror=cast-qual
-Werror=init-self
-Werror=cast-align
-Werror=unreachable-code
-Werror=strict-aliasing -fstrict-aliasing
-Werror=redundant-decls
-Werror=missing-declarations
-Werror=missing-field-initializers
-Werror=write-strings
-Werror=ctor-dtor-privacy
-Werror=switch-enum
-Werror=switch-default
-Werror=old-style-cast
-Werror=overloaded-virtual
-Werror=overloaded-virtual
-Werror=missing-include-dirs
-Werror=unused-result
-fstack-protector
-Wzero-as-null-pointer-constant
)
else()
set(BeamMP_CompileOptions
/bigobj
/INCREMENTAL:NO /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBCMT
)
endif()
set(BeamMP_Libraries
Boost::boost
Boost::system
doctest::doctest
OpenSSL::SSL
OpenSSL::Crypto
sol2::sol2
fmt::fmt fmt::fmt
doctest::doctest
Threads::Threads Threads::Threads
ZLIB::ZLIB commandline_static
toml11::toml11
rapidjson
sol2
httplib::httplib
libzip::zip
OpenSSL::SSL OpenSSL::Crypto
${LUA_LIBRARIES} ${LUA_LIBRARIES}
commandline
sentry
) )
if (WIN32) # add dependency find_package calls and similar here
set(BeamMP_PlatformLibs wsock32 ws2_32) find_package(fmt CONFIG REQUIRED)
endif () find_package(OpenSSL REQUIRED)
find_package(doctest CONFIG REQUIRED)
find_package(Boost REQUIRED)
find_package(httplib CONFIG REQUIRED)
find_package(libzip CONFIG REQUIRED)
find_package(RapidJSON CONFIG REQUIRED)
find_package(sol2 CONFIG REQUIRED)
find_package(toml11 CONFIG REQUIRED)
# ------------------------ BEAMMP SERVER ----------------------------- include_directories(include)
add_executable(BeamMP-Server # to enable multithreading and the Threads::Threads dependency
src/main.cpp include(FindThreads)
${BeamMP_Sources}
)
target_compile_definitions(BeamMP-Server PRIVATE ### END SETTINGS ###
${BeamMP_Definitions}
DOCTEST_CONFIG_DISABLE
)
target_compile_options(BeamMP-Server PRIVATE # DONT change anything beyond this point unless you've read the cmake bible and
${BeamMP_CompileOptions} # swore on it not to bonk up the ci/cd pipelines with your changes.
)
target_include_directories(BeamMP-Server PRIVATE ####################
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
target_include_directories(BeamMP-Server SYSTEM PRIVATE
${BeamMP_Includes}
)
target_link_libraries(BeamMP-Server # enables compile_commands.json for clang-related tools (such as the clang LS)
${BeamMP_Libraries} set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
${BeamMP_PlatformLibs}
)
# ------------------------ BEAMMP SERVER TESTS ----------------------- # build debug builds by default (if not specified otherwise)
if(NOT CMAKE_BUILD_TYPE)
option(BUILD_TESTS "Build BeamMP-Server tests" ON) set(CMAKE_BUILD_TYPE "Debug")
endif()
if(BUILD_TESTS)
add_executable(BeamMP-Server-tests if(UNIX)
test/test_main.cpp # this will allow to use same _DEBUG macro available in both Linux as well as Windows - MSCV environment. Easy to put Debug specific code.
${BeamMP_Sources} add_compile_options("$<$<CONFIG:DEBUG>:-D_DEBUG>")
) endif(UNIX)
target_compile_definitions(BeamMP-Server-tests PRIVATE if (WIN32)
${BeamMP_Definitions} add_compile_options("-D_WIN32_WINNT=0x0601")
) endif(WIN32)
target_compile_options(BeamMP-Server-tests PRIVATE
${BeamMP_CompileOptions} include(cmake/CompilerWarnings.cmake)
)
# set MT library for msvc - this is required (says documentation)
target_include_directories(BeamMP-Server-tests PRIVATE # linux/mac/etc should simply ignore this by default.
"${CMAKE_CURRENT_SOURCE_DIR}/include" set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
)
set(PRJ_DEFINITIONS ${PRJ_DEFINITIONS}
target_include_directories(BeamMP-Server-tests SYSTEM PRIVATE PRJ_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
${BeamMP_Includes} PRJ_VERSION_MINOR=${PROJECT_VERSION_MINOR}
) PRJ_VERSION_PATCH=${PROJECT_VERSION_PATCH}
)
target_link_libraries(BeamMP-Server-tests
${BeamMP_Libraries} # build commandline manually for funky windows flags to carry over without a custom toolchain file
${BeamMP_PlatformLibs} add_library(commandline_static
) deps/commandline/src/impls.h
deps/commandline/src/windows_impl.cpp
deps/commandline/src/linux_impl.cpp
deps/commandline/src/backends/InteractiveBackend.cpp
deps/commandline/src/backends/InteractiveBackend.h
deps/commandline/src/backends/Backend.cpp
deps/commandline/src/backends/Backend.h
deps/commandline/src/commandline.h
deps/commandline/src/commandline.cpp
deps/commandline/src/backends/BufferedBackend.cpp
deps/commandline/src/backends/BufferedBackend.h
)
if (WIN32)
target_compile_definitions(commandline_static PRIVATE -DPLATFORM_WINDOWS=1)
else ()
target_compile_definitions(commandline_static PRIVATE -DPLATFORM_LINUX=1)
endif ()
target_include_directories(commandline_static PUBLIC "deps/commandline/src")
target_link_libraries(commandline_static Threads::Threads)
# end of commandline custom build
add_executable(${PROJECT_NAME} ${PRJ_HEADERS} ${PRJ_SOURCES} ${PRJ_MAIN})
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
target_include_directories(${PROJECT_NAME} PRIVATE ${PRJ_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${PRJ_LIBRARIES})
target_compile_features(${PROJECT_NAME} PRIVATE ${PRJ_COMPILE_FEATURES})
target_compile_definitions(${PROJECT_NAME} PRIVATE ${PRJ_DEFINITIONS} ${PRJ_WARNINGS}
DOCTEST_CONFIG_DISABLE # disables all test code in the final executable
)
if(MSVC)
target_link_options(${PROJECT_NAME} PRIVATE "/SUBSYSTEM:CONSOLE")
endif(MSVC)
# setup all warnings (from cmake/CompilerWarnings.cmake)
set_project_warnings(${PROJECT_NAME})
if(${PROJECT_NAME}_ENABLE_UNIT_TESTING)
message(STATUS "Unit tests are enabled and will be built as '${PROJECT_NAME}-tests'")
add_executable(${PROJECT_NAME}-tests ${PRJ_HEADERS} ${PRJ_SOURCES} ${PRJ_TEST_MAIN})
target_include_directories(${PROJECT_NAME}-tests PRIVATE ${PRJ_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME}-tests ${PRJ_LIBRARIES})
target_compile_features(${PROJECT_NAME}-tests PRIVATE ${PRJ_COMPILE_FEATURES})
target_compile_definitions(${PROJECT_NAME}-tests PRIVATE ${PRJ_DEFINITIONS} ${PRJ_WARNINGS})
set_project_warnings(${PROJECT_NAME}-tests)
if(MSVC)
target_link_options(${PROJECT_NAME}-tests PRIVATE "/SUBSYSTEM:CONSOLE")
endif(MSVC)
endif() endif()
+1 -2
View File
@@ -117,7 +117,7 @@ Ubuntu 22.04
git git
libz-dev libz-dev
rapidjson-dev rapidjson-dev
liblua5.3 liblua5.3-dev
libssl-dev libssl-dev
libwebsocketpp-dev libwebsocketpp-dev
libcurl4-openssl-dev libcurl4-openssl-dev
@@ -142,7 +142,6 @@ curl
git git
cmake cmake
g++ g++
cmake
zlib zlib
boost boost
websocketpp websocketpp
+115
View File
@@ -0,0 +1,115 @@
# from here:
#
# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md
# Courtesy of Jason Turner
# License here: https://github.com/cpp-best-practices/cppbestpractices/blob/master/LICENSE
#
# This version has been modified by the owners of the current respository.
# Modifications have mostly been marked with "modified" or similar, though this is not
# strictly required.
function(set_project_warnings project_name)
set(MSVC_WARNINGS
/W4 # Baseline reasonable warnings
/w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss
# of data
/w14254 # 'operator': conversion from 'type1:field_bits' to
# 'type2:field_bits', possible loss of data
/w14263 # 'function': member function does not override any base class
# virtual member function
/w14265 # 'classname': class has virtual functions, but destructor is not
# virtual instances of this class may not be destructed correctly
/w14287 # 'operator': unsigned/negative constant mismatch
/we4289 # nonstandard extension used: 'variable': loop control variable
# declared in the for-loop is used outside the for-loop scope
/w14296 # 'operator': expression is always 'boolean_value'
/w14311 # 'variable': pointer truncation from 'type1' to 'type2'
/w14545 # expression before comma evaluates to a function which is missing
# an argument list
/w14546 # function call before comma missing argument list
/w14547 # 'operator': operator before comma has no effect; expected
# operator with side-effect
/w14549 # 'operator': operator before comma has no effect; did you intend
# 'operator'?
/w14555 # expression has no effect; expected expression with side- effect
/w14619 # pragma warning: there is no warning number 'number'
/w14640 # Enable warning on thread un-safe static member initialization
/w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may
# cause unexpected runtime behavior.
/w14905 # wide string literal cast to 'LPSTR'
/w14906 # string literal cast to 'LPWSTR'
/w14928 # illegal copy-initialization; more than one user-defined
# conversion has been implicitly applied
/permissive- # standards conformance mode for MSVC compiler.
)
set(CLANG_WARNINGS
-Wall
-Wextra # reasonable and standard
-Wshadow # warn the user if a variable declaration shadows one from a
# parent context
-Wnon-virtual-dtor # warn the user if a class with virtual functions has a
# non-virtual destructor. This helps catch hard to
# track down memory errors
-Wold-style-cast # warn for c-style casts
-Wcast-align # warn for potential performance problem casts
-Wunused # warn on anything being unused
-Woverloaded-virtual # warn if you overload (not override) a virtual
# function
-Wpedantic # warn if non-standard C++ is used
-Wconversion # warn on type conversions that may lose data
-Wsign-conversion # warn on sign conversions
-Wnull-dereference # warn if a null dereference is detected
-Wdouble-promotion # warn if float is implicit promoted to double
-Wformat=2 # warn on security issues around functions that format output
# (ie printf)
# modified; added more errors / warnings
# some have been set to be errors, but the option _WARNINGS_AS_ERRORS
# (see below) should still be used in strict pipelines.
-Werror=uninitialized
-Werror=float-equal
-Werror=write-strings
-Werror=strict-aliasing -fstrict-aliasing
-Werror=missing-declarations
-Werror=missing-field-initializers
-Werror=ctor-dtor-privacy
-Werror=switch-enum
-Wswitch-default
-Werror=unused-result
-Werror=implicit-fallthrough
-Werror=return-type
-Wmissing-include-dirs
)
if (${PROJECT_NAME}_WARNINGS_AS_ERRORS)
set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror)
set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX)
endif()
set(GCC_WARNINGS
${CLANG_WARNINGS}
-Wmisleading-indentation # warn if indentation implies blocks where blocks
# do not exist
-Wduplicated-cond # warn if if / else chain has duplicated conditions
-Wduplicated-branches # warn if if / else branches have duplicated code
-Wlogical-op # warn about logical operations being used where bitwise were
# probably wanted
# -Wuseless-cast # warn if you perform a cast to the same type (modified: removed)
)
if(MSVC)
set(PRJ_WARNINGS ${MSVC_WARNINGS})
elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
set(PRJ_WARNINGS ${CLANG_WARNINGS})
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(PRJ_WARNINGS ${GCC_WARNINGS})
else()
message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
endif()
target_compile_options(${project_name} PUBLIC ${PRJ_WARNINGS})
if(NOT TARGET ${project_name})
message(AUTHOR_WARNING "${project_name} is not a target, thus no compiler warning were added.")
endif()
endfunction()
+21
View File
@@ -0,0 +1,21 @@
find_package(Git)
if(${PROJECT_NAME}_CHECKOUT_GIT_SUBMODULES)
if(Git_FOUND)
message(STATUS "Git found, submodule update and init")
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT)
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
message(SEND_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules. This may result in missing dependencies.")
endif()
else()
message(SEND_ERROR "git required for checking out submodules, but not found. Submodules will not be checked out - this may result in missing dependencies.")
endif()
endif()
if(Git_FOUND)
else()
message(STATUS "Git not found - the version will not include a git hash.")
set(PRJ_GIT_HASH "unknown")
endif()
+44
View File
@@ -0,0 +1,44 @@
# Modified, original version from https://github.com/filipdutescu/modern-cpp-template (Unlicense)
option(${PROJECT_NAME}_WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF)
option(${PROJECT_NAME}_CHECKOUT_GIT_SUBMODULES "If git is found, initialize all submodules." ON)
option(${PROJECT_NAME}_ENABLE_UNIT_TESTING "Enable unit tests for the projects (from the `test` subfolder)." ON)
option(${PROJECT_NAME}_ENABLE_CLANG_TIDY "Enable static analysis with Clang-Tidy." OFF)
option(${PROJECT_NAME}_ENABLE_CPPCHECK "Enable static analysis with Cppcheck." OFF)
# TODO Implement code coverage
# option(${PROJECT_NAME}_ENABLE_CODE_COVERAGE "Enable code coverage through GCC." OFF)
option(${PROJECT_NAME}_ENABLE_DOXYGEN "Enable Doxygen documentation builds of source." OFF)
# Generate compile_commands.json for clang based tools
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Export all symbols when building a shared library
if(BUILD_SHARED_LIBS)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
endif()
option(${PROJECT_NAME}_ENABLE_LTO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)." OFF)
if(${PROJECT_NAME}_ENABLE_LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT result OUTPUT output)
if(result)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(SEND_ERROR "IPO is not supported: ${output}.")
endif()
endif()
option(${PROJECT_NAME}_ENABLE_CCACHE "Enable the usage of Ccache, in order to speed up rebuild times." ON)
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()
option(${PROJECT_NAME}_ENABLE_SANITIZER "Enable sanitizer to detect memory errors, undefined behavior, etc. (slows down the executable)." OFF)
if(${PROJECT_NAME}_ENABLE_SANITIZER)
add_compile_options(-fsanitize=address,undefined)
add_link_options(-fsanitize=address,undefined)
endif()
+20
View File
@@ -0,0 +1,20 @@
if(${PROJECT_NAME}_ENABLE_CLANG_TIDY)
find_program(CLANGTIDY clang-tidy)
if(CLANGTIDY)
set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option)
message("Clang-Tidy finished setting up.")
else()
message(SEND_ERROR "Clang-Tidy requested but executable not found.")
endif()
endif()
if(${PROJECT_NAME}_ENABLE_CPPCHECK)
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK ${CPPCHECK} --suppress=missingInclude --enable=all
--inline-suppr --inconclusive)
message("Cppcheck finished setting up.")
else()
message(SEND_ERROR "Cppcheck requested but executable not found.")
endif()
endif()
+17
View File
@@ -0,0 +1,17 @@
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake)
find_package(Git)
if(Git_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive vcpkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT)
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
message(SEND_ERROR "Checking out vcpkg in source tree failed with ${GIT_SUBMOD_RESULT}.")
endif()
else()
message(FATAL_ERROR "Could not find git or vcpkg.cmake. Please either, install git and re-run cmake (or run `git submodule update --init --recursive`), or install vcpkg and add `-DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/scripts/buildsystems/vcpkg.cmake` to your cmake invocation. Please try again after making those changes.")
endif()
endif()
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake)
endif()
-6
View File
@@ -1,6 +0,0 @@
include_directories("${PROJECT_SOURCE_DIR}/deps")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/commandline")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/fmt")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/sol2")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/doctest")
Vendored
-1
Submodule deps/asio deleted from 4915cfd8a1
-1
Submodule deps/cpp-httplib deleted from d92c314466
-1
Submodule deps/doctest deleted from b7c21ec5ce
Vendored
-1
Submodule deps/fmt deleted from c4ee726532
Vendored
-1
Submodule deps/json deleted from 69d744867f
Vendored
-1
Submodule deps/libzip deleted from 5532f9baa0
-1
Submodule deps/rapidjson deleted from 00dbcf2c6e
Submodule deps/sentry-native deleted from 28be51f5e3
Vendored
-1
Submodule deps/sol2 deleted from eba86625b7
Vendored
-1
Submodule deps/toml11 deleted from c7627ff6a1
+1 -4
View File
@@ -1,8 +1,5 @@
#pragma once #pragma once
#include "TSentry.h"
extern TSentry Sentry;
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <cstring> #include <cstring>
@@ -49,6 +46,7 @@ public:
std::string Resource { "Resources" }; std::string Resource { "Resources" };
std::string MapName { "/levels/gridmap_v2/info.json" }; std::string MapName { "/levels/gridmap_v2/info.json" };
std::string Key {}; std::string Key {};
std::string Password{};
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 { false }; bool HTTPServerEnabled { false };
@@ -192,7 +190,6 @@ void RegisterThread(const std::string& str);
#define beammp_error(x) \ #define beammp_error(x) \
do { \ do { \
Application::Console().Write(_this_location + std::string("[ERROR] ") + (x)); \ Application::Console().Write(_this_location + std::string("[ERROR] ") + (x)); \
Sentry.AddErrorBreadcrumb((x), _file_basename, _line); \
} while (false) } while (false)
#define beammp_lua_error(x) \ #define beammp_lua_error(x) \
do { \ do { \
-2
View File
@@ -63,12 +63,10 @@ inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const ch
bool result = (cond); \ bool result = (cond); \
if (!result) { \ if (!result) { \
beammp_errorf("Assertion failed in '{}:{}': {}.", __func__, _line, #cond); \ beammp_errorf("Assertion failed in '{}:{}': {}.", __func__, _line, #cond); \
Sentry.LogAssert(#cond, _file_basename, _line, __func__); \
} \ } \
} while (false) } while (false)
#define beammp_assert_not_reachable() \ #define beammp_assert_not_reachable() \
do { \ do { \
beammp_errorf("Assertion failed in '{}:{}': Unreachable code reached. This may result in a crash or undefined state of the program.", __func__, _line); \ beammp_errorf("Assertion failed in '{}:{}': Unreachable code reached. This may result in a crash or undefined state of the program.", __func__, _line); \
Sentry.LogAssert("code is unreachable", _file_basename, _line, __func__); \
} while (false) } while (false)
#endif // DEBUG #endif // DEBUG
+1 -1
View File
@@ -8,7 +8,7 @@ public:
IThreaded() IThreaded()
// invokes operator() on this object // invokes operator() on this object
: mThread() { } : mThread() { }
~IThreaded() noexcept { virtual ~IThreaded() noexcept {
if (mThread.joinable()) { if (mThread.joinable()) {
mThread.join(); mThread.join();
} }
+1 -1
View File
@@ -6,7 +6,7 @@
#include <filesystem> #include <filesystem>
#define TOML11_PRESERVE_COMMENTS_BY_DEFAULT #define TOML11_PRESERVE_COMMENTS_BY_DEFAULT
#include <toml11/toml.hpp> // header-only version of TOML++ #include <toml.hpp> // header-only version of TOML++
namespace fs = std::filesystem; namespace fs = std::filesystem;
+1
View File
@@ -5,6 +5,7 @@
#include <atomic> #include <atomic>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <mutex>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
+14 -4
View File
@@ -13,11 +13,14 @@
#include <queue> #include <queue>
#include <random> #include <random>
#include <set> #include <set>
#include <toml11/toml.hpp> #include <toml.hpp>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#define SOL_ALL_SAFETIES_ON 1 #define SOL_ALL_SAFETIES_ON 1
#define SOL_USER_C_ASSERT SOL_ON
#define SOL_C_ASSERT(...) \
beammp_lua_errorf("SOL2 assertion failure: Assertion `{}` failed in {}:{}. This *should* be a fatal error, but BeamMP Server overrides it to not be fatal. This may cause the Lua Engine to crash, or cause other issues.", #__VA_ARGS__, __FILE__, __LINE__)
#include <sol/sol.hpp> #include <sol/sol.hpp>
using TLuaStateId = std::string; using TLuaStateId = std::string;
@@ -41,7 +44,14 @@ struct TLuaResult {
sol::object Result { sol::lua_nil }; sol::object Result { sol::lua_nil };
TLuaStateId StateId; TLuaStateId StateId;
std::string Function; std::string Function;
// TODO: Add condition_variable std::shared_ptr<std::mutex> ReadyMutex {
std::make_shared<std::mutex>()
};
std::shared_ptr<std::condition_variable> ReadyCondition {
std::make_shared<std::condition_variable>()
};
void MarkAsReady();
void WaitUntilReady(); void WaitUntilReady();
}; };
@@ -98,8 +108,8 @@ public:
return mLuaStates.size(); return mLuaStates.size();
} }
std::vector<std::string> GetLuaStateNames() { std::vector<std::string> GetLuaStateNames() {
std::vector<std::string> names{}; std::vector<std::string> names {};
for(auto const& [stateId, _ ] : mLuaStates) { for (auto const& [stateId, _] : mLuaStates) {
names.push_back(stateId); names.push_back(stateId);
} }
return names; return names;
+1
View File
@@ -52,4 +52,5 @@ private:
static const uint8_t* SendSplit(TClient& c, ip::tcp::socket& Socket, const uint8_t* DataPtr, size_t Size); static const uint8_t* SendSplit(TClient& c, ip::tcp::socket& Socket, const uint8_t* DataPtr, size_t Size);
}; };
std::string HashPassword(const std::string& str);
std::vector<uint8_t> StringToVector(const std::string& Str); std::vector<uint8_t> StringToVector(const std::string& Str);
+1
View File
@@ -9,6 +9,7 @@ class TNetwork;
class TPPSMonitor : public IThreaded { class TPPSMonitor : public IThreaded {
public: public:
explicit TPPSMonitor(TServer& Server); explicit TPPSMonitor(TServer& Server);
virtual ~TPPSMonitor() {}
void operator()() override; void operator()() override;
-38
View File
@@ -1,38 +0,0 @@
#ifndef SENTRY_H
#define SENTRY_H
#include <mutex>
#include <string>
#include <unordered_map>
enum class SentryLevel {
Debug = -1,
Info = 0,
Warning = 1,
Error = 2,
Fatal = 3,
};
// singleton, dont make this twice
class TSentry final {
public:
TSentry();
~TSentry();
void PrintWelcome();
void SetupUser();
void Log(SentryLevel level, const std::string& logger, const std::string& text);
void LogError(const std::string& text, const std::string& file, const std::string& line);
void SetContext(const std::string& context_name, const std::unordered_map<std::string, std::string>& map);
void LogException(const std::exception& e, const std::string& file, const std::string& line);
void LogAssert(const std::string& condition_string, const std::string& file, const std::string& line, const std::string& function);
void AddErrorBreadcrumb(const std::string& msg, const std::string& file, const std::string& line);
// cleared when Logged
void SetTransaction(const std::string& id);
[[nodiscard]] std::unique_lock<std::mutex> CreateExclusiveContext();
private:
bool mValid { true };
std::mutex mMutex;
};
#endif // SENTRY_H
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
set -ex
apt-get update -y
apt-get install -y liblua5.3-0 liblua5.3-dev curl zip unzip tar cmake make git g++
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
set -ex
git config --global --add safe.directory $(pwd)
git config --global --add safe.directory $(pwd)/vcpkg
git config --global --add safe.directory $(pwd)/deps/commandline
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
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
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server-tests
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -ex
apt-get update -y
apt-get install -y liblua5.3-0 curl
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
set -ex
apt-get update -y
apt-get install -y liblua5.3-0 liblua5.3-dev curl zip unzip tar cmake make git g++
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
set -ex
git config --global --add safe.directory $(pwd)
git config --global --add safe.directory $(pwd)/vcpkg
git config --global --add safe.directory $(pwd)/deps/commandline
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
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
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server-tests
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -ex
apt-get update -y
apt-get install -y liblua5.3-0 curl
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake . -B bin $1 -DCMAKE_BUILD_TYPE=Release -DBeamMP-Server_ENABLE_LTO=ON -DVCPKG_TARGET_TRIPLET=x64-windows-static
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server-tests
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -ex
cmake --build bin --parallel -t BeamMP-Server
+2 -2
View File
@@ -51,7 +51,7 @@ TClient::TVehicleDataLockPair TClient::GetAllCars() {
std::string TClient::GetCarPositionRaw(int Ident) { std::string TClient::GetCarPositionRaw(int Ident) {
std::unique_lock lock(mVehiclePositionMutex); std::unique_lock lock(mVehiclePositionMutex);
try { try {
return mVehiclePosition.at(Ident); return mVehiclePosition.at(size_t(Ident));
} catch (const std::out_of_range& oor) { } catch (const std::out_of_range& oor) {
return ""; return "";
} }
@@ -73,7 +73,7 @@ void TClient::Disconnect(std::string_view Reason) {
void TClient::SetCarPosition(int Ident, const std::string& Data) { void TClient::SetCarPosition(int Ident, const std::string& Data) {
std::unique_lock lock(mVehiclePositionMutex); std::unique_lock lock(mVehiclePositionMutex);
mVehiclePosition[Ident] = Data; mVehiclePosition[size_t(Ident)] = Data;
} }
std::string TClient::GetCarData(int Ident) { std::string TClient::GetCarData(int Ident) {
-6
View File
@@ -13,9 +13,6 @@
#include "CustomAssert.h" #include "CustomAssert.h"
#include "Http.h" #include "Http.h"
// global, yes, this is ugly, no, it cant be done another way
TSentry Sentry {};
Application::TSettings Application::Settings = {}; Application::TSettings Application::Settings = {};
void Application::RegisterShutdownHandler(const TShutdownHandler& Handler) { void Application::RegisterShutdownHandler(const TShutdownHandler& Handler) {
@@ -217,9 +214,6 @@ void Application::CheckForUpdates() {
if (FirstTime) { if (FirstTime) {
beammp_debug("Failed to fetch version from: " + url); beammp_debug("Failed to fetch version from: " + url);
beammp_trace("got " + Response); 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::Bad);
} }
} }
+5
View File
@@ -18,6 +18,7 @@ static constexpr std::string_view StrDescription = "Description";
static constexpr std::string_view StrResourceFolder = "ResourceFolder"; static constexpr std::string_view StrResourceFolder = "ResourceFolder";
static constexpr std::string_view StrAuthKey = "AuthKey"; static constexpr std::string_view StrAuthKey = "AuthKey";
static constexpr std::string_view StrLogChat = "LogChat"; static constexpr std::string_view StrLogChat = "LogChat";
static constexpr std::string_view StrPassword = "Password";
// Misc // Misc
static constexpr std::string_view StrSendErrors = "SendErrors"; static constexpr std::string_view StrSendErrors = "SendErrors";
@@ -106,6 +107,8 @@ void TConfig::FlushToFile() {
data["General"][StrMap.data()] = Application::Settings.MapName; data["General"][StrMap.data()] = Application::Settings.MapName;
data["General"][StrDescription.data()] = Application::Settings.ServerDesc; data["General"][StrDescription.data()] = Application::Settings.ServerDesc;
data["General"][StrResourceFolder.data()] = Application::Settings.Resource; data["General"][StrResourceFolder.data()] = Application::Settings.Resource;
data["General"][StrPassword.data()] = Application::Settings.Password;
SetComment(data["General"][StrPassword.data()].comments(), " Sets a password on this server, which restricts people from joining. To join, a player must enter this exact password. Leave empty ("") to disable the password.");
// Misc // Misc
data["Misc"][StrHideUpdateMessages.data()] = Application::Settings.HideUpdateMessages; 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."); 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.");
@@ -189,6 +192,7 @@ void TConfig::ParseFromFile(std::string_view name) {
TryReadValue(data, "General", StrResourceFolder, Application::Settings.Resource); TryReadValue(data, "General", StrResourceFolder, Application::Settings.Resource);
TryReadValue(data, "General", StrAuthKey, Application::Settings.Key); TryReadValue(data, "General", StrAuthKey, Application::Settings.Key);
TryReadValue(data, "General", StrLogChat, Application::Settings.LogChat); TryReadValue(data, "General", StrLogChat, Application::Settings.LogChat);
TryReadValue(data, "General", StrPassword, Application::Settings.Password);
// Misc // Misc
TryReadValue(data, "Misc", StrSendErrors, Application::Settings.SendErrors); TryReadValue(data, "Misc", StrSendErrors, Application::Settings.SendErrors);
TryReadValue(data, "Misc", StrHideUpdateMessages, Application::Settings.HideUpdateMessages); TryReadValue(data, "Misc", StrHideUpdateMessages, Application::Settings.HideUpdateMessages);
@@ -240,6 +244,7 @@ void TConfig::PrintDebug() {
beammp_debug(std::string(StrHTTPServerIP) + ": \"" + Application::Settings.HTTPServerIP + "\""); beammp_debug(std::string(StrHTTPServerIP) + ": \"" + Application::Settings.HTTPServerIP + "\"");
// special! // special!
beammp_debug("Key Length: " + std::to_string(Application::Settings.Key.length()) + ""); beammp_debug("Key Length: " + std::to_string(Application::Settings.Key.length()) + "");
beammp_debug("Password Protected: " + std::string(Application::Settings.Password.empty() ? "false" : "true"));
} }
void TConfig::ParseOldFormat() { void TConfig::ParseOldFormat() {
+2 -4
View File
@@ -8,6 +8,7 @@
#include "TLuaEngine.h" #include "TLuaEngine.h"
#include <ctime> #include <ctime>
#include <mutex>
#include <sstream> #include <sstream>
static inline bool StringStartsWith(const std::string& What, const std::string& StartsWith) { static inline bool StringStartsWith(const std::string& What, const std::string& StartsWith) {
@@ -353,7 +354,6 @@ void TConsole::Command_Settings(const std::string&, const std::vector<std::strin
if (!EnsureArgsCount(args, 1, 2)) { if (!EnsureArgsCount(args, 1, 2)) {
return; return;
} }
} }
void TConsole::Command_Say(const std::string& FullCmd) { void TConsole::Command_Say(const std::string& FullCmd) {
@@ -606,9 +606,7 @@ TConsole::TConsole() {
HandleLuaInternalCommand(cmd.substr(1)); HandleLuaInternalCommand(cmd.substr(1));
} else { } else {
auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(TrimmedCmd), "", "" }); auto Future = mLuaEngine->EnqueueScript(mStateId, { std::make_shared<std::string>(TrimmedCmd), "", "" });
while (!Future->Ready) { Future->WaitUntilReady();
std::this_thread::yield(); // TODO: Add a timeout
}
if (Future->Error) { if (Future->Error) {
beammp_lua_error("error in " + mStateId + ": " + Future->ErrorMessage); beammp_lua_error("error in " + mStateId + ": " + Future->ErrorMessage);
} }
+3 -18
View File
@@ -40,16 +40,6 @@ void THeartbeatThread::operator()() {
Body += "&ip=" + Application::Settings.CustomIP; Body += "&ip=" + Application::Settings.CustomIP;
} }
auto SentryReportError = [&](const std::string& transaction, int status) {
auto Lock = Sentry.CreateExclusiveContext();
Sentry.SetContext("heartbeat",
{ { "response-body", T },
{ "request-body", Body } });
Sentry.SetTransaction(transaction);
beammp_trace("sending log to sentry: " + std::to_string(status) + " for " + transaction);
Sentry.Log(SentryLevel::Error, "default", Http::Status::ToString(status) + " (" + std::to_string(status) + ")");
};
auto Target = "/heartbeat"; auto Target = "/heartbeat";
unsigned int ResponseCode = 0; unsigned int ResponseCode = 0;
@@ -63,10 +53,8 @@ void THeartbeatThread::operator()() {
beammp_trace("Backend response failed to parse as valid json"); beammp_trace("Backend response failed to parse as valid json");
beammp_trace("Response was: `" + T + "`"); beammp_trace("Response was: `" + T + "`");
} }
Sentry.SetContext("JSON Response", { { "reponse", T } });
SentryReportError(Url + Target, ResponseCode);
} else if (ResponseCode != 200) { } else if (ResponseCode != 200) {
SentryReportError(Url + Target, ResponseCode); beammp_errorf("Response code from the heartbeat: {}", ResponseCode);
} else { } else {
// all ok // all ok
Ok = true; Ok = true;
@@ -85,24 +73,20 @@ void THeartbeatThread::operator()() {
if (Doc.HasMember(StatusKey) && Doc[StatusKey].IsString()) { if (Doc.HasMember(StatusKey) && Doc[StatusKey].IsString()) {
Status = Doc[StatusKey].GetString(); Status = Doc[StatusKey].GetString();
} else { } else {
Sentry.SetContext("JSON Response", { { StatusKey, "invalid string / missing" } });
Ok = false; Ok = false;
} }
if (Doc.HasMember(CodeKey) && Doc[CodeKey].IsString()) { if (Doc.HasMember(CodeKey) && Doc[CodeKey].IsString()) {
Code = Doc[CodeKey].GetString(); Code = Doc[CodeKey].GetString();
} else { } else {
Sentry.SetContext("JSON Response", { { CodeKey, "invalid string / missing" } });
Ok = false; Ok = false;
} }
if (Doc.HasMember(MessageKey) && Doc[MessageKey].IsString()) { if (Doc.HasMember(MessageKey) && Doc[MessageKey].IsString()) {
Message = Doc[MessageKey].GetString(); Message = Doc[MessageKey].GetString();
} else { } else {
Sentry.SetContext("JSON Response", { { MessageKey, "invalid string / missing" } });
Ok = false; Ok = false;
} }
if (!Ok) { if (!Ok) {
beammp_error("Missing/invalid json members in backend response"); beammp_error("Missing/invalid json members in backend response");
Sentry.LogError("Missing/invalid json members in backend response", __FILE__, std::to_string(__LINE__));
} }
} else { } else {
if (!Application::Settings.Private) { if (!Application::Settings.Private) {
@@ -149,7 +133,8 @@ std::string THeartbeatThread::GenerateCall() {
<< "&modstotalsize=" << mResourceManager.MaxModSize() << "&modstotalsize=" << mResourceManager.MaxModSize()
<< "&modstotal=" << mResourceManager.ModsLoaded() << "&modstotal=" << mResourceManager.ModsLoaded()
<< "&playerslist=" << GetPlayers() << "&playerslist=" << GetPlayers()
<< "&desc=" << Application::Settings.ServerDesc; << "&desc=" << Application::Settings.ServerDesc
<< "&pass=" << (Application::Settings.Password.empty() ? "false" : "true");
return Ret.str(); return Ret.str();
} }
THeartbeatThread::THeartbeatThread(TResourceManager& ResourceManager, TServer& Server) THeartbeatThread::THeartbeatThread(TResourceManager& ResourceManager, TServer& Server)
+18 -8
View File
@@ -286,6 +286,7 @@ void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results, c
bool Cancelled = false; bool Cancelled = false;
size_t ms = 0; size_t ms = 0;
std::set<std::string> WarnedResults; std::set<std::string> WarnedResults;
while (!Result->Ready && !Cancelled) { while (!Result->Ready && !Cancelled) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
ms += 10; ms += 10;
@@ -300,6 +301,7 @@ void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results, c
} }
} }
} }
if (Cancelled) { if (Cancelled) {
beammp_lua_warn("'" + Result->Function + "' in '" + Result->StateId + "' failed to execute in time and was not waited for. It may still finish executing at a later time."); beammp_lua_warn("'" + Result->Function + "' in '" + Result->StateId + "' failed to execute in time and was not waited for. It may still finish executing at a later time.");
LuaAPI::MP::Engine->ReportErrors({ Result }); LuaAPI::MP::Engine->ReportErrors({ Result });
@@ -425,7 +427,7 @@ sol::table TLuaEngine::StateThreadData::Lua_TriggerGlobalEvent(const std::string
Result->Error = true; Result->Error = true;
Result->ErrorMessage = "Function result in TriggerGlobalEvent was invalid"; Result->ErrorMessage = "Function result in TriggerGlobalEvent was invalid";
} }
Result->Ready = true; Result->MarkAsReady();
Return.push_back(Result); Return.push_back(Result);
} }
} }
@@ -955,7 +957,7 @@ void TLuaEngine::StateThreadData::operator()() {
sol::error Err = Res; sol::error Err = Res;
S.second->ErrorMessage = Err.what(); S.second->ErrorMessage = Err.what();
} }
S.second->Ready = true; S.second->MarkAsReady();
} }
} }
{ // StateFunctionQueue Scope { // StateFunctionQueue Scope
@@ -1016,11 +1018,11 @@ void TLuaEngine::StateThreadData::operator()() {
sol::error Err = Res; sol::error Err = Res;
Result->ErrorMessage = Err.what(); Result->ErrorMessage = Err.what();
} }
Result->Ready = true; Result->MarkAsReady();
} else { } else {
Result->Error = true; Result->Error = true;
Result->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later Result->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later
Result->Ready = true; Result->MarkAsReady();
} }
} }
} }
@@ -1070,11 +1072,19 @@ void TLuaEngine::StateThreadData::AddPath(const fs::path& Path) {
mPaths.push(Path); mPaths.push(Path);
} }
void TLuaResult::WaitUntilReady() { void TLuaResult::MarkAsReady() {
while (!Ready) { {
std::this_thread::yield(); std::lock_guard<std::mutex> readyLock(*this->ReadyMutex);
std::this_thread::sleep_for(std::chrono::milliseconds(10)); this->Ready = true;
} }
this->ReadyCondition->notify_all();
}
void TLuaResult::WaitUntilReady() {
std::unique_lock readyLock(*this->ReadyMutex);
// wait if not ready yet
if(!this->Ready)
this->ReadyCondition->wait(readyLock);
} }
TLuaChunk::TLuaChunk(std::shared_ptr<std::string> Content, std::string FileName, std::string PluginPath) TLuaChunk::TLuaChunk(std::shared_ptr<std::string> Content, std::string FileName, std::string PluginPath)
+30 -1
View File
@@ -11,6 +11,8 @@
#include <boost/asio/ip/address_v4.hpp> #include <boost/asio/ip/address_v4.hpp>
#include <cstring> #include <cstring>
typedef boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO> rcv_timeout_option;
std::vector<uint8_t> StringToVector(const std::string& Str) { std::vector<uint8_t> StringToVector(const std::string& Str) {
return std::vector<uint8_t>(Str.data(), Str.data() + Str.size()); return std::vector<uint8_t>(Str.data(), Str.data() + Str.size());
} }
@@ -225,6 +227,15 @@ void TNetwork::HandleDownload(TConnection&& Conn) {
}); });
} }
std::string HashPassword(const std::string& str) {
std::stringstream ret;
unsigned char* hash = SHA256(reinterpret_cast<const unsigned char*>(str.c_str()), str.length(), nullptr);
for (int i = 0; i < 32; i++) {
ret << std::hex << static_cast<int>(hash[i]);
}
return ret.str();
}
std::shared_ptr<TClient> TNetwork::Authentication(TConnection&& RawConnection) { std::shared_ptr<TClient> TNetwork::Authentication(TConnection&& RawConnection) {
auto Client = CreateClient(std::move(RawConnection.Socket)); auto Client = CreateClient(std::move(RawConnection.Socket));
Client->SetIdentifier("ip", RawConnection.SockAddr.address().to_string()); Client->SetIdentifier("ip", RawConnection.SockAddr.address().to_string());
@@ -248,7 +259,8 @@ std::shared_ptr<TClient> TNetwork::Authentication(TConnection&& RawConnection) {
ClientKick(*Client, fmt::format("Invalid version header: '{}' ({})", std::string(reinterpret_cast<const char*>(Data.data()), Data.size()), Data.size())); ClientKick(*Client, fmt::format("Invalid version header: '{}' ({})", std::string(reinterpret_cast<const char*>(Data.data()), Data.size()), Data.size()));
return nullptr; return nullptr;
} }
if (!TCPSend(*Client, StringToVector("S"))) {
if (!TCPSend(*Client, StringToVector("A"))) { //changed to A for Accepted version
// TODO: handle // TODO: handle
} }
@@ -304,6 +316,22 @@ std::shared_ptr<TClient> TNetwork::Authentication(TConnection&& RawConnection) {
return nullptr; return nullptr;
} }
if(!Application::Settings.Password.empty()) { // ask password
if(!TCPSend(*Client, StringToVector("S"))) {
// TODO: handle
}
beammp_info("Waiting for password");
Data = TCPRcv(*Client);
std::string Pass = std::string(reinterpret_cast<const char*>(Data.data()), Data.size());
if(Pass != HashPassword(Application::Settings.Password)) {
beammp_debug(Client->GetName() + " attempted to connect with a wrong password");
ClientKick(*Client, "Wrong password!");
return {};
} else {
beammp_debug(Client->GetName() + " used the correct password");
}
}
beammp_debug("Name -> " + Client->GetName() + ", Guest -> " + std::to_string(Client->IsGuest()) + ", Roles -> " + Client->GetRoles()); beammp_debug("Name -> " + Client->GetName() + ", Guest -> " + std::to_string(Client->IsGuest()) + ", Roles -> " + Client->GetRoles());
mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool { mServer.ForEachClient([&](const std::weak_ptr<TClient>& ClientPtr) -> bool {
std::shared_ptr<TClient> Cl; std::shared_ptr<TClient> Cl;
@@ -353,6 +381,7 @@ std::shared_ptr<TClient> TNetwork::Authentication(TConnection&& RawConnection) {
} else { } else {
ClientKick(*Client, "Server full!"); ClientKick(*Client, "Server full!");
} }
return Client; return Client;
} }
-138
View File
@@ -1,138 +0,0 @@
#include "TSentry.h"
#include "Common.h"
#include <cstring>
#include <sentry.h>
#include <sstream>
TSentry::TSentry() {
if (std::strlen(S_DSN) == /* DISABLES CODE */ (0)) {
mValid = false;
} else {
mValid = true;
sentry_options_t* options = sentry_options_new();
sentry_options_set_dsn(options, S_DSN);
auto ReleaseString = "BeamMP-Server@" + Application::ServerVersionString();
sentry_options_set_symbolize_stacktraces(options, true);
sentry_options_set_release(options, ReleaseString.c_str());
sentry_options_set_max_breadcrumbs(options, 10);
sentry_init(options);
}
}
TSentry::~TSentry() {
if (mValid) {
sentry_close();
}
}
void TSentry::PrintWelcome() {
if (mValid) {
if (!Application::Settings.SendErrors) {
mValid = false;
if (Application::Settings.SendErrorsMessageEnabled) {
beammp_info("Opted out of error reporting (SendErrors), Sentry disabled.");
} else {
beammp_info("Sentry disabled");
}
} else {
if (Application::Settings.SendErrorsMessageEnabled) {
beammp_info("Sentry started! Reporting errors automatically. This sends data to the developers in case of errors and crashes. You can learn more, turn this message off or opt-out of this in the ServerConfig.toml.");
} else {
beammp_info("Sentry started");
}
}
} else {
if (Application::Settings.SendErrorsMessageEnabled) {
beammp_info("Sentry disabled in unofficial build. Automatic error reporting disabled.");
} else {
beammp_info("Sentry disabled in unofficial build");
}
}
}
void TSentry::SetupUser() {
if (!mValid) {
return;
}
Application::SetSubsystemStatus("Sentry", Application::Status::Good);
sentry_value_t user = sentry_value_new_object();
if (Application::Settings.Key.size() == 36) {
sentry_value_set_by_key(user, "id", sentry_value_new_string(Application::Settings.Key.c_str()));
} else {
sentry_value_set_by_key(user, "id", sentry_value_new_string("unauthenticated"));
}
sentry_set_user(user);
}
void TSentry::Log(SentryLevel level, const std::string& logger, const std::string& text) {
if (!mValid) {
return;
}
SetContext("threads", { { "thread-name", ThreadName(true) } });
auto Msg = sentry_value_new_message_event(sentry_level_t(level), logger.c_str(), text.c_str());
sentry_capture_event(Msg);
sentry_set_transaction(nullptr);
}
void TSentry::LogError(const std::string& text, const std::string& file, const std::string& line) {
if (!mValid) {
return;
}
SetTransaction(file + ":" + line);
Log(SentryLevel::Error, "default", file + ": " + text);
}
void TSentry::SetContext(const std::string& context_name, const std::unordered_map<std::string, std::string>& map) {
if (!mValid) {
return;
}
auto ctx = sentry_value_new_object();
for (const auto& pair : map) {
std::string key = pair.first;
if (key == "type") {
// `type` is reserved
key = "_type";
}
sentry_value_set_by_key(ctx, key.c_str(), sentry_value_new_string(pair.second.c_str()));
}
sentry_set_context(context_name.c_str(), ctx);
}
void TSentry::LogException(const std::exception& e, const std::string& file, const std::string& line) {
if (!mValid) {
return;
}
SetTransaction(file + ":" + line);
Log(SentryLevel::Fatal, "exceptions", std::string(e.what()) + " @ " + file + ":" + line);
}
void TSentry::LogAssert(const std::string& condition_string, const std::string& file, const std::string& line, const std::string& function) {
if (!mValid) {
return;
}
SetTransaction(file + ":" + line + ":" + function);
std::stringstream ss;
ss << "\"" << condition_string << "\" failed @ " << file << ":" << line;
Log(SentryLevel::Fatal, "asserts", ss.str());
}
void TSentry::AddErrorBreadcrumb(const std::string& msg, const std::string& file, const std::string& line) {
if (!mValid) {
return;
}
auto crumb = sentry_value_new_breadcrumb("default", (msg + " @ " + file + ":" + line).c_str());
sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error"));
sentry_add_breadcrumb(crumb);
}
void TSentry::SetTransaction(const std::string& id) {
if (!mValid) {
return;
}
sentry_set_transaction(id.c_str());
}
std::unique_lock<std::mutex> TSentry::CreateExclusiveContext() {
return std::unique_lock<std::mutex>(mMutex);
}
+1 -11
View File
@@ -382,23 +382,13 @@ void TServer::Apply(TClient& c, int VID, const std::string& pckt) {
std::string VD = c.GetCarData(VID); std::string VD = c.GetCarData(VID);
if (VD.empty()) { if (VD.empty()) {
beammp_error("Tried to apply change to vehicle that does not exist"); beammp_error("Tried to apply change to vehicle that does not exist");
auto Lock = Sentry.CreateExclusiveContext();
Sentry.SetContext("vehicle-change",
{ { "packet", Packet },
{ "vehicle-id", std::to_string(VID) },
{ "client-car-count", std::to_string(c.GetCarCount()) } });
Sentry.LogError("attempt to apply change to nonexistent vehicle", _file_basename, _line);
return; return;
} }
std::string Header = VD.substr(0, VD.find('{')); std::string Header = VD.substr(0, VD.find('{'));
FoundPos = VD.find('{'); FoundPos = VD.find('{');
if (FoundPos == std::string::npos) { if (FoundPos == std::string::npos) {
auto Lock = Sentry.CreateExclusiveContext(); return;
Sentry.SetContext("vehicle-change-packet",
{ { "packet", VD } });
Sentry.LogError("malformed packet", _file_basename, _line);
return;
} }
VD = VD.substr(FoundPos); VD = VD.substr(FoundPos);
rapidjson::Document Veh, Pack; rapidjson::Document Veh, Pack;
-5
View File
@@ -1,5 +1,3 @@
#include "TSentry.h"
#include "ArgsParser.h" #include "ArgsParser.h"
#include "Common.h" #include "Common.h"
#include "Http.h" #include "Http.h"
@@ -64,7 +62,6 @@ int main(int argc, char** argv) {
} catch (const std::exception& e) { } catch (const std::exception& e) {
beammp_error("A fatal exception has occurred and the server is forcefully shutting down."); beammp_error("A fatal exception has occurred and the server is forcefully shutting down.");
beammp_error(e.what()); beammp_error(e.what());
Sentry.LogException(e, _file_basename, _line);
MainRet = -1; MainRet = -1;
} }
std::exit(MainRet); std::exit(MainRet);
@@ -148,8 +145,6 @@ int BeamMPServerMain(MainArguments Arguments) {
RegisterThread("Main"); RegisterThread("Main");
beammp_trace("Running in debug mode on a debug build"); beammp_trace("Running in debug mode on a debug build");
Sentry.SetupUser();
Sentry.PrintWelcome();
TResourceManager ResourceManager; TResourceManager ResourceManager;
TPPSMonitor PPSMonitor(Server); TPPSMonitor PPSMonitor(Server);
THeartbeatThread Heartbeat(ResourceManager, Server); THeartbeatThread Heartbeat(ResourceManager, Server);
Submodule
+1
Submodule vcpkg added at 72010900b7
+19
View File
@@ -0,0 +1,19 @@
{
"name": "server",
"version-string": "0.1.0",
"dependencies": [
"fmt",
"doctest",
"boost-asio",
"boost-variant",
"boost-spirit",
"boost-uuid",
"cpp-httplib",
"toml11",
"libzip",
"rapidjson",
"nlohmann-json",
"openssl",
"sol2"
]
}