Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/cmake-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CMake MacOS Build

on: [push, pull_request, workflow_dispatch]

env:
BUILD_TYPE: Release

jobs:
macos-build:
runs-on: macos-latest

steps:
- uses: actions/checkout@v2
with:
submodules: 'true'

- name: Configure macOS SDK
run: |
echo "SDKROOT=$(xcrun --show-sdk-path)" >> $GITHUB_ENV
echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> $GITHUB_ENV

- name: Restore artifacts, or run vcpkg, build and cache artifacts
uses: lukka/run-vcpkg@v7
id: runvcpkg
with:
vcpkgArguments: 'zlib:arm64-osx nlohmann-json:arm64-osx openssl:arm64-osx cpp-httplib[openssl]:arm64-osx curl:arm64-osx'
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
vcpkgGitCommitId: '40616a5e954f7be1077ef37db3fbddbd5dcd1ca6'

- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build-macos

- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build-macos
run: |
cmake $GITHUB_WORKSPACE \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake' \
-DCMAKE_OSX_ARCHITECTURES=arm64

- name: Build
working-directory: ${{github.workspace}}/build-macos
shell: bash
run: cmake --build . --config $BUILD_TYPE

- name: Archive artifacts
uses: actions/upload-artifact@v4
with:
name: BeamMP-Launcher
path: ${{github.workspace}}/build-macos/BeamMP-Launcher
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ cmake-build-release
/*.sh
/*.obj
/*.exe
.DS_Store/
.cache/
.https_debug/
Launcher.cfg
Expand All @@ -13,3 +14,9 @@ bin/
compile_commands.json
key
out/
vcpkg_installed/

build-linux/
build-macos/
build-windows/

2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (WIN32)
find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 httplib::httplib nlohmann_json::nlohmann_json CURL::libcurl)
elseif (UNIX)
elseif (UNIX OR APPLE)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE
Expand Down
6 changes: 4 additions & 2 deletions include/Network/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
#include <filesystem>
#include <string>

#ifdef __linux__
#if defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#if defined(__linux__)
#include <bits/types/siginfo_t.h>
#include <cstdint>
#include <sys/ucontext.h>
#endif
#include <cstdint>
#include <arpa/inet.h>
#endif

Expand Down
2 changes: 1 addition & 1 deletion include/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
struct Options {
#if defined(_WIN32)
std::string executable_name = "BeamMP-Launcher.exe";
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
std::string executable_name = "BeamMP-Launcher";
#endif
unsigned int port = 4444;
Expand Down
16 changes: 15 additions & 1 deletion src/GameStart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#if defined(_WIN32)
#include <shlobj.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "vdf_parser.hpp"
#include <pwd.h>
#include <spawn.h>
Expand Down Expand Up @@ -128,6 +128,18 @@ std::filesystem::path GetGamePath() {
Path += "current/";
return Path;
}
#elif defined(__APPLE__)
std::filesystem::path GetGamePath() {
// Right now only steam is supported
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on this comment?

struct passwd* pw = getpwuid(getuid());
std::string homeDir = pw->pw_dir;

std::string Path = homeDir + "/Library/Application Support/BeamNG/BeamNG.drive/";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the user data folder always be in this location?

std::string Ver = CheckVer(GetGameDir());
Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1));
Path += "current/";
return Path;
}
#endif

#if defined(_WIN32)
Expand Down Expand Up @@ -204,9 +216,11 @@ void StartGame(std::string Dir) {
}
#endif

#if !defined(__APPLE__)
void InitGame(const beammp_fs_string& Dir) {
if (!options.no_launch) {
std::thread Game(StartGame, Dir);
Game.detach();
}
}
#endif
20 changes: 9 additions & 11 deletions src/Network/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <shellapi.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <cstring>
#include <errno.h>
#include <netdb.h>
Expand Down Expand Up @@ -481,19 +482,16 @@ int Handle(EXCEPTION_POINTERS* ep) {

[[noreturn]] void CoreNetwork() {
while (true) {
#if not defined(__MINGW32__)
#if defined(_WIN32) && not defined(__MINGW32__)
__try {
#endif

CoreMain();

#if not defined(__MINGW32__) and not defined(__linux__)
} __except (Handle(GetExceptionInformation())) { }
#elif not defined(__MINGW32__) and defined(__linux__)
}
catch (...) {
except("(Core) Code : " + std::string(strerror(errno)));
}
#elif defined(__linux__) || defined(__APPLE__)
try {
CoreMain();
} catch (...) {
except("(Core) Code : " + std::string(strerror(errno)));
}
#endif

std::this_thread::sleep_for(std::chrono::seconds(1));
Expand Down
7 changes: 6 additions & 1 deletion src/Network/DNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

#if defined(_WIN32)
#include <winsock2.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <arpa/inet.h>
#include <netdb.h>
#include <cstring>
#endif

#include "Logger.h"
Expand All @@ -33,10 +34,14 @@ std::string GetAddr(const std::string& IP) {
host = gethostbyname(IP.c_str());
if (!host) {
error("DNS lookup failed! on " + IP);
#if defined(_WIN32)
WSACleanup();
#endif
return "DNS";
}
std::string Ret = inet_ntoa(*((struct in_addr*)host->h_addr));
#if defined(_WIN32)
WSACleanup();
#endif
return Ret;
}
2 changes: 1 addition & 1 deletion src/Network/GlobalHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <arpa/inet.h>
#include <cstring>
Expand Down
3 changes: 2 additions & 1 deletion src/Network/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

#if defined(_WIN32)
#include <ws2tcpip.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <arpa/inet.h>
#include <cstring>
#include <errno.h>
Expand Down
4 changes: 2 additions & 2 deletions src/Network/VehicleData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#if defined(_WIN32)
#include <ws2tcpip.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <arpa/inet.h>
#include <cstring>
Expand Down Expand Up @@ -65,7 +65,7 @@ void UDPRcv() {
sockaddr_in FromServer {};
#if defined(_WIN32)
int clientLength = sizeof(FromServer);
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
socklen_t clientLength = sizeof(FromServer);
#endif
ZeroMemory(&FromServer, clientLength);
Expand Down
3 changes: 2 additions & 1 deletion src/Network/VehicleEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

#if defined(_WIN32)
#include <ws2tcpip.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "linuxfixes.h"
#include <arpa/inet.h>
#include <cstring>
#include <errno.h>
Expand Down
37 changes: 35 additions & 2 deletions src/Security/BeamNG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <filesystem>
#if defined(_WIN32)
#include <shlobj_core.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
#include "vdf_parser.hpp"
#include <pwd.h>
#include <unistd.h>
Expand All @@ -18,6 +18,7 @@
#include "Utils.h"

#include <fstream>
#include <iostream>
#include <string>
#include <thread>

Expand All @@ -38,7 +39,7 @@ void lowExit(int code) {
beammp_fs_string GetGameDir() {
#if defined(_WIN32)
return GameDir.substr(0, GameDir.find_last_of('\\'));
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
return GameDir.substr(0, GameDir.find_last_of('/'));
#endif
}
Expand Down Expand Up @@ -278,6 +279,38 @@ void LegitimacyCheck() {
error("The game directory was not found.");
return;
}
#elif defined(__APPLE__)
// On macOS, ask the user to provide the game directory path
info("Please enter the path to your BeamNG.drive installation directory:");
info("Example: /Users/YourName/Library/Application Support/Steam/steamapps/common/BeamNG.drive");
std::cout << "Game directory path: ";

std::string userPath;
std::getline(std::cin, userPath);
Comment on lines +284 to +289
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could command line arguments be used instead of this interface?


// Remove trailing slash if present
if (!userPath.empty() && (userPath.back() == '/' || userPath.back() == '\\')) {
userPath.pop_back();
}
Comment on lines +291 to +294
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could std::filesystem::path be used for this instead?


std::filesystem::path gamePath(userPath);

// Check if the path exists and contains integrity.json
if (!std::filesystem::exists(gamePath)) {
error("The specified path does not exist: " + userPath);
lowExit(8);
return;
}

std::filesystem::path integrityPath = gamePath / "integrity.json";
if (!std::filesystem::exists(integrityPath)) {
error("The specified path does not appear to be a valid BeamNG.drive installation (integrity.json not found).");
lowExit(9);
return;
}

GameDir = gamePath.string() + "/";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could std::filesystem::path be used here as well?

info("Game directory set to: " + GameDir);
#endif
}
std::string CheckVer(const std::filesystem::path& dir) {
Expand Down
12 changes: 6 additions & 6 deletions src/Startup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Version::Version(const std::array<uint8_t, 3>& v)
beammp_fs_string GetEN() {
#if defined(_WIN32)
return L"BeamMP-Launcher.exe";
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
return "BeamMP-Launcher";
#endif
}
Expand Down Expand Up @@ -150,7 +150,7 @@ void URelaunch() {
std::this_thread::sleep_for(std::chrono::seconds(1));
exit(1);
}
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
void ReLaunch() {
std::string Arg;
for (int c = 2; c <= options.argc; c++) {
Expand Down Expand Up @@ -181,7 +181,7 @@ void URelaunch() {
void CheckName() {
#if defined(_WIN32)
std::wstring DN = GetEN(), CDir = Utils::ToWString(options.executable_name), FN = CDir.substr(CDir.find_last_of('\\') + 1);
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
std::string DN = GetEN(), CDir = options.executable_name, FN = CDir.substr(CDir.find_last_of('/') + 1);
#endif
if (FN != DN) {
Expand Down Expand Up @@ -280,7 +280,7 @@ void InitLauncher() {
CheckLocalKey();
CheckForUpdates(std::string(GetVer()) + GetPatch());
}
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)

void InitLauncher() {
info("BeamMP Launcher v" + GetVer() + GetPatch());
Expand Down Expand Up @@ -367,8 +367,8 @@ void PreGame(const beammp_fs_string& GamePath) {
}
#if defined(_WIN32)
std::wstring ZipPath(GetGamePath() / LR"(mods\multiplayer\BeamMP.zip)");
#elif defined(__linux__)
// Linux version of the game cant handle mods with uppercase names
#elif defined(__linux__) || defined(__APPLE__)
// Linux and macOS versions of the game cant handle mods with uppercase names
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the mac version the windows version of the game running with a translations layer, making it able to handle uppercase names?

std::string ZipPath(GetGamePath() / R"(mods/multiplayer/beammp.zip)");
#endif

Expand Down
4 changes: 3 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ int main(int argc, const char** argv) try {
error(std::string("Failed to start HTTP proxy: Some in-game functions may not work. Error: ") + e.what());
}
PreGame(GetGameDir());
InitGame(GetGameDir());
#if !defined(__APPLE__)
InitGame(GetGameDir());
#endif
CoreNetwork();
} catch (const std::exception& e) {
error(std::string("Exception in main(): ") + e.what());
Expand Down