From 2946ceff5b1092c46c84cb06e503befc16b33150 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 19:46:33 +0100 Subject: [PATCH 01/99] Mac Build --- .github/workflows/cmake-macos.yml | 42 +++++++++++++++++++++++++++++++ CMakeLists.txt | 7 ++++++ 2 files changed, 49 insertions(+) create mode 100644 .github/workflows/cmake-macos.yml diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml new file mode 100644 index 00000000..cff7810a --- /dev/null +++ b/.github/workflows/cmake-macos.yml @@ -0,0 +1,42 @@ +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: Restore artifacts, or run vcpkg, build and cache artifacts + uses: lukka/run-vcpkg@v7 + id: runvcpkg + with: + vcpkgArguments: 'zlib nlohmann-json openssl cpp-httplib[openssl]' + 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' + + - 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index ad74591e..1c7c924e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ if (WIN32) message(STATUS "MSVC -> forcing use of statically-linked runtime.") STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) +elseif(APPLE) + set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for MacOS" FORCE) endif(WIN32) set(CMAKE_CXX_STANDARD 20) @@ -32,6 +34,11 @@ elseif (LINUX) find_package(OpenSSL REQUIRED) target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) +elseif(APPLE) + find_package(ZLIB REQUIRED) + find_package(OpenSSL REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE + ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) else(WIN32) #MINGW add_definitions("-D_WIN32_WINNT=0x0600") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s --static") From ccde804f7e0c766bc538b216bde7a50303441195 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 19:58:41 +0100 Subject: [PATCH 02/99] fix --- src/GameStart.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 194d13b9..509fd2e0 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -132,6 +132,11 @@ void StartGame(std::string Dir) { std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); } + +#elif defined(__APPLE__) +void StartGame(std::string Dir) { + error("Please launch the game manually for now"); +} #endif void InitGame(const std::string& Dir) { From c6eab33f63579d4ef8e3459c407ec0c92b288592 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 20:08:45 +0100 Subject: [PATCH 03/99] fixes --- include/linuxfixes.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/include/linuxfixes.h b/include/linuxfixes.h index 730e880f..debadb69 100644 --- a/include/linuxfixes.h +++ b/include/linuxfixes.h @@ -16,4 +16,24 @@ #define ZeroMemory(mem, len) memset(mem, 0, len) -#endif \ No newline at end of file +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#include + +#define SOCKET int +#define SOCKADDR sockaddr +#define SOCKADDR_IN sockaddr_in +#define WSAGetLastError() errno +#define closesocket close +#define SD_BOTH SHUT_RDWR +#define WSACleanup() +#define SOCKET_ERROR -1 + +#define ZeroMemory(mem, len) memset(mem, 0, len) +#endif + +#endif From f1f02b46f33effa4f017d1717e92b5ff4ff7a2e8 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 20:55:39 +0100 Subject: [PATCH 04/99] Update linuxfixes.h --- include/linuxfixes.h | 45 +++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/include/linuxfixes.h b/include/linuxfixes.h index debadb69..fc6033a1 100644 --- a/include/linuxfixes.h +++ b/include/linuxfixes.h @@ -2,29 +2,17 @@ #define _LINUXFIXES_H #include - -// Translate windows sockets stuff to linux sockets -#define SOCKET uint64_t -#define SOCKADDR sockaddr -#define SOCKADDR_IN sockaddr_in -#define WSAGetLastError() errno -#define closesocket close -#define SD_BOTH SHUT_RDWR -// We dont need wsacleanup -#define WSACleanup() -#define SOCKET_ERROR -1 - -#define ZeroMemory(mem, len) memset(mem, 0, len) - -#ifdef __APPLE__ #include #include #include +#include #include #include #include +#include -#define SOCKET int +// Translate windows sockets stuff to linux sockets +#define SOCKET uint64_t #define SOCKADDR sockaddr #define SOCKADDR_IN sockaddr_in #define WSAGetLastError() errno @@ -32,8 +20,31 @@ #define SD_BOTH SHUT_RDWR #define WSACleanup() #define SOCKET_ERROR -1 - +#define INVALID_SOCKET (-1) #define ZeroMemory(mem, len) memset(mem, 0, len) + +// Socket constants that need to be defined +#ifndef AF_INET +#define AF_INET PF_INET +#endif + +#ifndef SOCK_STREAM +#define SOCK_STREAM 1 +#endif + +#ifndef IPPROTO_TCP +#define IPPROTO_TCP 6 +#endif + +#ifndef AI_PASSIVE +#define AI_PASSIVE 0x00000001 +#endif + +#ifdef __APPLE__ +// MacOS specific includes already covered above +// Just need to redefine SOCKET as int for MacOS +#undef SOCKET +#define SOCKET int #endif #endif From d74da8f4b6ba0f80646a69603dc84c7873a87f0a Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:03:36 +0100 Subject: [PATCH 05/99] Update linuxfixes.h --- include/linuxfixes.h | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/include/linuxfixes.h b/include/linuxfixes.h index fc6033a1..730e880f 100644 --- a/include/linuxfixes.h +++ b/include/linuxfixes.h @@ -2,14 +2,6 @@ #define _LINUXFIXES_H #include -#include -#include -#include -#include -#include -#include -#include -#include // Translate windows sockets stuff to linux sockets #define SOCKET uint64_t @@ -18,33 +10,10 @@ #define WSAGetLastError() errno #define closesocket close #define SD_BOTH SHUT_RDWR +// We dont need wsacleanup #define WSACleanup() #define SOCKET_ERROR -1 -#define INVALID_SOCKET (-1) -#define ZeroMemory(mem, len) memset(mem, 0, len) - -// Socket constants that need to be defined -#ifndef AF_INET -#define AF_INET PF_INET -#endif - -#ifndef SOCK_STREAM -#define SOCK_STREAM 1 -#endif -#ifndef IPPROTO_TCP -#define IPPROTO_TCP 6 -#endif - -#ifndef AI_PASSIVE -#define AI_PASSIVE 0x00000001 -#endif - -#ifdef __APPLE__ -// MacOS specific includes already covered above -// Just need to redefine SOCKET as int for MacOS -#undef SOCKET -#define SOCKET int -#endif +#define ZeroMemory(mem, len) memset(mem, 0, len) -#endif +#endif \ No newline at end of file From 9de4fdc3808778b454c0f6d5f95783348cd07876 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:04:26 +0100 Subject: [PATCH 06/99] Update Core.cpp --- src/Network/Core.cpp | 133 ++++++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 52 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 6202c372..7a432f23 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -10,18 +10,20 @@ #include "Security/Init.h" #include #include + #if defined(_WIN32) -#include -#include -#elif defined(__linux__) -#include -#include -#include -#include -#include -#include -#include -#include + #include + #include +#elif defined(__linux__) || defined(__APPLE__) + #include + #include + #include + #include + #include + #include + #include + #include + extern char **environ; #endif #include "Logger.h" @@ -47,7 +49,13 @@ std::string UlStatus; std::string MStatus; bool ModLoaded; int ping = -1; -SOCKET CoreSocket = -1; + +#if defined(_WIN32) + SOCKET CoreSocket = INVALID_SOCKET; +#else + int CoreSocket = -1; +#endif + signed char confirmed = -1; bool SecurityWarning() { @@ -70,7 +78,7 @@ bool SecurityWarning() { void StartSync(const std::string& Data) { std::string IP = GetAddr(Data.substr(1, Data.find(':') - 1)); - if (IP.find('.') == -1) { + if (IP.find('.') == std::string::npos) { if (IP == "DNS") UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; else @@ -92,24 +100,24 @@ void StartSync(const std::string& Data) { std::mutex sendMutex; -void CoreSend(std::string data) { - std::lock_guard lock(sendMutex); - +void CoreSend(const std::string& data) { + std::lock_guard lock(sendMutex); + if (CoreSocket != -1) { - int res = send(CoreSocket, (data + "\n").c_str(), int(data.size()) + 1, 0); + int res = send(CoreSocket, (data + "\n").c_str(), static_cast(data.size()) + 1, 0); if (res < 0) { - debug("(Core) send failed with error: " + std::to_string(WSAGetLastError())); + debug("(Core) send failed with error: " + std::to_string(errno)); } } } bool IsAllowedLink(const std::string& Link) { - std::regex link_pattern(R"(https:\/\/(?:\w+)?(?:\.)?(?:beammp\.com|beammp\.gg|github.com\/BeamMP\/|discord\.gg|patreon\.com\/BeamMP))"); + std::regex link_pattern(R"(https:\/\/(?:\w+)?(?:\.)?(?:beammp\.com|beammp\.gg|github\.com\/BeamMP\/|discord\.gg|patreon\.com\/BeamMP))"); std::smatch link_match; return std::regex_search(Link, link_match, link_pattern) && link_match.position() == 0; } -void Parse(std::string Data, SOCKET CSocket) { +void Parse(std::string Data, int CSocket) { char Code = Data.at(0), SubCode = 0; if (Data.length() > 1) SubCode = Data.at(1); @@ -133,16 +141,14 @@ void Parse(std::string Data, SOCKET CSocket) { break; case 'O': // open default browser with URL if (IsAllowedLink(Data.substr(1))) { -#if defined(__linux) - if (char* browser = getenv("BROWSER"); browser != nullptr && !std::string_view(browser).empty()) { +#if defined(__linux__) || defined(__APPLE__) + if (const char* browser = getenv("BROWSER"); browser != nullptr && !std::string_view(browser).empty()) { pid_t pid; auto arg = Data.substr(1); - char* argv[] = { browser, arg.data() }; + char* argv[] = { const_cast(browser), arg.data(), nullptr }; auto status = posix_spawn(&pid, browser, nullptr, nullptr, argv, environ); if (status == 0) { debug("Browser PID: " + std::to_string(pid)); - // we don't wait for it to exit, because we just don't care. - // typically, you'd waitpid() here. } else { error("Failed to open the following link in the browser (error follows below): " + arg); error(std::string("posix_spawn: ") + strerror(status)); @@ -150,8 +156,8 @@ void Parse(std::string Data, SOCKET CSocket) { } else { error("Failed to open the following link in the browser because the $BROWSER environment variable is not set: " + Data.substr(1)); } -#elif defined(WIN32) - ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr, SW_SHOW); /// TODO: Look at when working on linux port +#elif defined(_WIN32) + ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr, SW_SHOW); #endif info("Opening Link \"" + Data.substr(1) + "\""); @@ -243,7 +249,8 @@ void Parse(std::string Data, SOCKET CSocket) { if (!Data.empty()) CoreSend(Data); } -void GameHandler(SOCKET Client) { + +void GameHandler(int Client) { CoreSocket = Client; int32_t Size, Temp, Rcv; char Header[10] = { 0 }; @@ -282,11 +289,12 @@ void GameHandler(SOCKET Client) { if (Temp == 0) { debug("(Core) Connection closing"); } else { - debug("(Core) recv failed with error: " + std::to_string(WSAGetLastError())); + debug("(Core) recv failed with error: " + std::to_string(errno)); } NetReset(); KillSocket(Client); } + void localRes() { MStatus = " "; UlStatus = "Ulstart"; @@ -297,20 +305,24 @@ void localRes() { } ConfList = new std::set; } + void CoreMain() { debug("Core Network on start! port: " + std::to_string(options.port)); - SOCKET LSocket, CSocket; + int LSocket, CSocket; struct addrinfo* res = nullptr; - struct addrinfo hints { }; + struct addrinfo hints {}; int iRes; -#ifdef _WIN32 + +#if defined(_WIN32) WSADATA wsaData; - iRes = WSAStartup(514, &wsaData); // 2.2 - if (iRes) + iRes = WSAStartup(MAKEWORD(2, 2), &wsaData); // 2.2 + if (iRes) { debug("WSAStartup failed with error: " + std::to_string(iRes)); + return; + } #endif - ZeroMemory(&hints, sizeof(hints)); + memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -319,36 +331,44 @@ void CoreMain() { iRes = getaddrinfo("127.0.0.1", std::to_string(options.port).c_str(), &hints, &res); if (iRes) { debug("(Core) addr info failed with error: " + std::to_string(iRes)); +#if defined(_WIN32) WSACleanup(); +#endif return; } LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (LSocket == -1) { - debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); + if (LSocket == INVALID_SOCKET) { + debug("(Core) socket failed with error: " + std::to_string(errno)); freeaddrinfo(res); +#if defined(_WIN32) WSACleanup(); +#endif return; } iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); if (iRes == SOCKET_ERROR) { - error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); + error("(Core) bind failed with error: " + std::to_string(errno)); freeaddrinfo(res); KillSocket(LSocket); +#if defined(_WIN32) WSACleanup(); +#endif return; } iRes = listen(LSocket, SOMAXCONN); if (iRes == SOCKET_ERROR) { - debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); + debug("(Core) listen failed with error: " + std::to_string(errno)); freeaddrinfo(res); KillSocket(LSocket); +#if defined(_WIN32) WSACleanup(); +#endif return; } do { CSocket = accept(LSocket, nullptr, nullptr); if (CSocket == -1) { - error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); + error("(Core) accept failed with error: " + std::to_string(errno)); continue; } localRes(); @@ -357,36 +377,45 @@ void CoreMain() { warn("Game Reconnecting..."); } while (CSocket); KillSocket(LSocket); +#if defined(_WIN32) WSACleanup(); +#endif } #if defined(_WIN32) int Handle(EXCEPTION_POINTERS* ep) { - char* hex = new char[100]; + char hex[100]; sprintf_s(hex, 100, "%lX", ep->ExceptionRecord->ExceptionCode); except("(Core) Code : " + std::string(hex)); - delete[] hex; return 1; } #endif [[noreturn]] void CoreNetwork() { while (true) { -#if not defined(__MINGW32__) +#if defined(_WIN32) __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))); - } +#else + try { + CoreMain(); + } catch (const std::exception& e) { + except("(Core) Exception: " + std::string(e.what())); + } #endif std::this_thread::sleep_for(std::chrono::seconds(1)); } } + +#if !defined(_WIN32) +typedef int SOCKET; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define WSAGetLastError() errno +#define WSACleanup() +#define KillSocket(s) close(s) +#else +#define KillSocket(s) closesocket(s) +#endif \ No newline at end of file From 1c683c2eb8fa712f35a45aa67d47d92ef5feb964 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:09:45 +0100 Subject: [PATCH 07/99] Update Core.cpp --- src/Network/Core.cpp | 60 +++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 7a432f23..da66b225 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -5,6 +5,7 @@ /// /// Created by Anonymous275 on 7/20/2020 /// + #include "Http.h" #include "Network/network.hpp" #include "Security/Init.h" @@ -14,7 +15,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) || defined(__APPLE__) +#else // For both Linux and macOS #include #include #include @@ -37,6 +38,18 @@ #include +// Définitions pour plateformes non Windows +#if !defined(_WIN32) +typedef int SOCKET; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define WSAGetLastError() errno +#define WSACleanup() +#define KillSocket(s) close(s) +#else +#define KillSocket(s) closesocket(s) +#endif + extern int TraceBack; std::set* ConfList = nullptr; bool TCPTerminate = false; @@ -49,13 +62,7 @@ std::string UlStatus; std::string MStatus; bool ModLoaded; int ping = -1; - -#if defined(_WIN32) - SOCKET CoreSocket = INVALID_SOCKET; -#else - int CoreSocket = -1; -#endif - +SOCKET CoreSocket = INVALID_SOCKET; signed char confirmed = -1; bool SecurityWarning() { @@ -103,10 +110,10 @@ std::mutex sendMutex; void CoreSend(const std::string& data) { std::lock_guard lock(sendMutex); - if (CoreSocket != -1) { + if (CoreSocket != INVALID_SOCKET) { int res = send(CoreSocket, (data + "\n").c_str(), static_cast(data.size()) + 1, 0); if (res < 0) { - debug("(Core) send failed with error: " + std::to_string(errno)); + debug("(Core) send failed with error: " + std::to_string(WSAGetLastError())); } } } @@ -117,7 +124,7 @@ bool IsAllowedLink(const std::string& Link) { return std::regex_search(Link, link_match, link_pattern) && link_match.position() == 0; } -void Parse(std::string Data, int CSocket) { +void Parse(std::string Data, SOCKET CSocket) { char Code = Data.at(0), SubCode = 0; if (Data.length() > 1) SubCode = Data.at(1); @@ -250,7 +257,7 @@ void Parse(std::string Data, int CSocket) { CoreSend(Data); } -void GameHandler(int Client) { +void GameHandler(SOCKET Client) { CoreSocket = Client; int32_t Size, Temp, Rcv; char Header[10] = { 0 }; @@ -289,7 +296,7 @@ void GameHandler(int Client) { if (Temp == 0) { debug("(Core) Connection closing"); } else { - debug("(Core) recv failed with error: " + std::to_string(errno)); + debug("(Core) recv failed with error: " + std::to_string(WSAGetLastError())); } NetReset(); KillSocket(Client); @@ -308,7 +315,7 @@ void localRes() { void CoreMain() { debug("Core Network on start! port: " + std::to_string(options.port)); - int LSocket, CSocket; + SOCKET LSocket, CSocket; struct addrinfo* res = nullptr; struct addrinfo hints {}; int iRes; @@ -338,7 +345,7 @@ void CoreMain() { } LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (LSocket == INVALID_SOCKET) { - debug("(Core) socket failed with error: " + std::to_string(errno)); + debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); #if defined(_WIN32) WSACleanup(); @@ -347,7 +354,7 @@ void CoreMain() { } iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); if (iRes == SOCKET_ERROR) { - error("(Core) bind failed with error: " + std::to_string(errno)); + error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); KillSocket(LSocket); #if defined(_WIN32) @@ -357,7 +364,7 @@ void CoreMain() { } iRes = listen(LSocket, SOMAXCONN); if (iRes == SOCKET_ERROR) { - debug("(Core) listen failed with error: " + std::to_string(errno)); + debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); KillSocket(LSocket); #if defined(_WIN32) @@ -367,15 +374,15 @@ void CoreMain() { } do { CSocket = accept(LSocket, nullptr, nullptr); - if (CSocket == -1) { - error("(Core) accept failed with error: " + std::to_string(errno)); + if (CSocket == INVALID_SOCKET) { + error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); continue; } localRes(); info("Game Connected!"); GameHandler(CSocket); warn("Game Reconnecting..."); - } while (CSocket); + } while (CSocket != INVALID_SOCKET); KillSocket(LSocket); #if defined(_WIN32) WSACleanup(); @@ -407,15 +414,4 @@ int Handle(EXCEPTION_POINTERS* ep) { std::this_thread::sleep_for(std::chrono::seconds(1)); } -} - -#if !defined(_WIN32) -typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define WSAGetLastError() errno -#define WSACleanup() -#define KillSocket(s) close(s) -#else -#define KillSocket(s) closesocket(s) -#endif \ No newline at end of file +} \ No newline at end of file From 601225744bea02ac7e24c1d63629b4e09ad92d60 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:16:53 +0100 Subject: [PATCH 08/99] Go back --- src/Network/Core.cpp | 117 +++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 71 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index da66b225..da6fc017 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -5,26 +5,23 @@ /// /// Created by Anonymous275 on 7/20/2020 /// - #include "Http.h" #include "Network/network.hpp" #include "Security/Init.h" #include #include - #if defined(_WIN32) - #include - #include -#else // For both Linux and macOS - #include - #include - #include - #include - #include - #include - #include - #include - extern char **environ; +#include +#include +#elif defined(__linux__) +#include +#include +#include +#include +#include +#include +#include +#include #endif #include "Logger.h" @@ -38,18 +35,6 @@ #include -// Définitions pour plateformes non Windows -#if !defined(_WIN32) -typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define WSAGetLastError() errno -#define WSACleanup() -#define KillSocket(s) close(s) -#else -#define KillSocket(s) closesocket(s) -#endif - extern int TraceBack; std::set* ConfList = nullptr; bool TCPTerminate = false; @@ -62,7 +47,7 @@ std::string UlStatus; std::string MStatus; bool ModLoaded; int ping = -1; -SOCKET CoreSocket = INVALID_SOCKET; +SOCKET CoreSocket = -1; signed char confirmed = -1; bool SecurityWarning() { @@ -85,7 +70,7 @@ bool SecurityWarning() { void StartSync(const std::string& Data) { std::string IP = GetAddr(Data.substr(1, Data.find(':') - 1)); - if (IP.find('.') == std::string::npos) { + if (IP.find('.') == -1) { if (IP == "DNS") UlStatus = "UlConnection Failed! (DNS Lookup Failed)"; else @@ -107,11 +92,11 @@ void StartSync(const std::string& Data) { std::mutex sendMutex; -void CoreSend(const std::string& data) { - std::lock_guard lock(sendMutex); - - if (CoreSocket != INVALID_SOCKET) { - int res = send(CoreSocket, (data + "\n").c_str(), static_cast(data.size()) + 1, 0); +void CoreSend(std::string data) { + std::lock_guard lock(sendMutex); + + if (CoreSocket != -1) { + int res = send(CoreSocket, (data + "\n").c_str(), int(data.size()) + 1, 0); if (res < 0) { debug("(Core) send failed with error: " + std::to_string(WSAGetLastError())); } @@ -119,7 +104,7 @@ void CoreSend(const std::string& data) { } bool IsAllowedLink(const std::string& Link) { - std::regex link_pattern(R"(https:\/\/(?:\w+)?(?:\.)?(?:beammp\.com|beammp\.gg|github\.com\/BeamMP\/|discord\.gg|patreon\.com\/BeamMP))"); + std::regex link_pattern(R"(https:\/\/(?:\w+)?(?:\.)?(?:beammp\.com|beammp\.gg|github.com\/BeamMP\/|discord\.gg|patreon\.com\/BeamMP))"); std::smatch link_match; return std::regex_search(Link, link_match, link_pattern) && link_match.position() == 0; } @@ -148,14 +133,16 @@ void Parse(std::string Data, SOCKET CSocket) { break; case 'O': // open default browser with URL if (IsAllowedLink(Data.substr(1))) { -#if defined(__linux__) || defined(__APPLE__) - if (const char* browser = getenv("BROWSER"); browser != nullptr && !std::string_view(browser).empty()) { +#if defined(__linux) + if (char* browser = getenv("BROWSER"); browser != nullptr && !std::string_view(browser).empty()) { pid_t pid; auto arg = Data.substr(1); - char* argv[] = { const_cast(browser), arg.data(), nullptr }; + char* argv[] = { browser, arg.data() }; auto status = posix_spawn(&pid, browser, nullptr, nullptr, argv, environ); if (status == 0) { debug("Browser PID: " + std::to_string(pid)); + // we don't wait for it to exit, because we just don't care. + // typically, you'd waitpid() here. } else { error("Failed to open the following link in the browser (error follows below): " + arg); error(std::string("posix_spawn: ") + strerror(status)); @@ -163,8 +150,8 @@ void Parse(std::string Data, SOCKET CSocket) { } else { error("Failed to open the following link in the browser because the $BROWSER environment variable is not set: " + Data.substr(1)); } -#elif defined(_WIN32) - ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr, SW_SHOW); +#elif defined(WIN32) + ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr, SW_SHOW); /// TODO: Look at when working on linux port #endif info("Opening Link \"" + Data.substr(1) + "\""); @@ -256,7 +243,6 @@ void Parse(std::string Data, SOCKET CSocket) { if (!Data.empty()) CoreSend(Data); } - void GameHandler(SOCKET Client) { CoreSocket = Client; int32_t Size, Temp, Rcv; @@ -301,7 +287,6 @@ void GameHandler(SOCKET Client) { NetReset(); KillSocket(Client); } - void localRes() { MStatus = " "; UlStatus = "Ulstart"; @@ -312,24 +297,20 @@ void localRes() { } ConfList = new std::set; } - void CoreMain() { debug("Core Network on start! port: " + std::to_string(options.port)); SOCKET LSocket, CSocket; struct addrinfo* res = nullptr; - struct addrinfo hints {}; + struct addrinfo hints { }; int iRes; - -#if defined(_WIN32) +#ifdef _WIN32 WSADATA wsaData; - iRes = WSAStartup(MAKEWORD(2, 2), &wsaData); // 2.2 - if (iRes) { + iRes = WSAStartup(514, &wsaData); // 2.2 + if (iRes) debug("WSAStartup failed with error: " + std::to_string(iRes)); - return; - } #endif - memset(&hints, 0, sizeof(hints)); + ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -338,18 +319,14 @@ void CoreMain() { iRes = getaddrinfo("127.0.0.1", std::to_string(options.port).c_str(), &hints, &res); if (iRes) { debug("(Core) addr info failed with error: " + std::to_string(iRes)); -#if defined(_WIN32) WSACleanup(); -#endif return; } LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (LSocket == INVALID_SOCKET) { + if (LSocket == -1) { debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); -#if defined(_WIN32) WSACleanup(); -#endif return; } iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); @@ -357,9 +334,7 @@ void CoreMain() { error("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); KillSocket(LSocket); -#if defined(_WIN32) WSACleanup(); -#endif return; } iRes = listen(LSocket, SOMAXCONN); @@ -367,14 +342,12 @@ void CoreMain() { debug("(Core) listen failed with error: " + std::to_string(WSAGetLastError())); freeaddrinfo(res); KillSocket(LSocket); -#if defined(_WIN32) WSACleanup(); -#endif return; } do { CSocket = accept(LSocket, nullptr, nullptr); - if (CSocket == INVALID_SOCKET) { + if (CSocket == -1) { error("(Core) accept failed with error: " + std::to_string(WSAGetLastError())); continue; } @@ -382,34 +355,36 @@ void CoreMain() { info("Game Connected!"); GameHandler(CSocket); warn("Game Reconnecting..."); - } while (CSocket != INVALID_SOCKET); + } while (CSocket); KillSocket(LSocket); -#if defined(_WIN32) WSACleanup(); -#endif } #if defined(_WIN32) int Handle(EXCEPTION_POINTERS* ep) { - char hex[100]; + char* hex = new char[100]; sprintf_s(hex, 100, "%lX", ep->ExceptionRecord->ExceptionCode); except("(Core) Code : " + std::string(hex)); + delete[] hex; return 1; } #endif [[noreturn]] void CoreNetwork() { while (true) { -#if defined(_WIN32) +#if not defined(__MINGW32__) __try { +#endif + CoreMain(); + +#if not defined(__MINGW32__) and not defined(__linux__) } __except (Handle(GetExceptionInformation())) { } -#else - try { - CoreMain(); - } catch (const std::exception& e) { - except("(Core) Exception: " + std::string(e.what())); - } +#elif not defined(__MINGW32__) and defined(__linux__) + } + catch (...) { + except("(Core) Code : " + std::string(strerror(errno))); + } #endif std::this_thread::sleep_for(std::chrono::seconds(1)); From 584c02fad7f003cc9db9b4585ab675f0a02863d7 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:21:17 +0100 Subject: [PATCH 09/99] fix --- src/Network/Core.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index da6fc017..dd8776b2 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -22,6 +22,12 @@ #include #include #include +#elif defined(__APPLE__) +#include +#include +#include +#include +#include #endif #include "Logger.h" From 7f1d1472968e2ae3e5ccade960131eb7b8ac27a0 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:25:51 +0100 Subject: [PATCH 10/99] fix --- src/Network/Core.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index dd8776b2..a0a085c0 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -13,7 +13,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include #include #include @@ -22,12 +22,6 @@ #include #include #include -#elif defined(__APPLE__) -#include -#include -#include -#include -#include #endif #include "Logger.h" From 0975ac883cc9ef3641609ca9cf5a22b34838db4d Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:36:22 +0100 Subject: [PATCH 11/99] fix with linux fix --- src/Network/Core.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index a0a085c0..3303eeb5 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "linuxfixes.h" #endif #include "Logger.h" From bec19a370805b967ca1215724f596ec9d4f5faf3 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:43:12 +0100 Subject: [PATCH 12/99] Update Core.cpp --- src/Network/Core.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 3303eeb5..ea5cf4ee 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -373,21 +373,19 @@ int Handle(EXCEPTION_POINTERS* ep) { [[noreturn]] void CoreNetwork() { while (true) { -#if not defined(__MINGW32__) +#if defined(_WIN32) __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 (const std::exception& e) { + except("(Core) Exception: " + std::string(e.what())); + } catch (...) { + except("(Core) Unknown exception"); + } #endif - std::this_thread::sleep_for(std::chrono::seconds(1)); } } \ No newline at end of file From 86d59a2340397000f7f92d0417a9105773ce9bfc Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:47:51 +0100 Subject: [PATCH 13/99] Update DNS.cpp --- src/Network/DNS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index d28b829f..9c77c356 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -10,7 +10,7 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include From 368d2499e1e6cd783da13d9037f3663298b8a9b5 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:51:50 +0100 Subject: [PATCH 14/99] fixes --- src/Network/GlobalHandler.cpp | 2 +- src/Network/VehicleData.cpp | 2 +- src/Network/VehicleEvent.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index cde06848..07854a58 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -11,7 +11,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 860724ce..7113c05a 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -11,7 +11,7 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index cc70ef6f..abb34ef8 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -14,7 +14,8 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) +#include "linuxfixes.h" #include #include #include From 15ac42e90f3dd03d872750add88f879066708be5 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:55:21 +0100 Subject: [PATCH 15/99] Update Resources.cpp --- src/Network/Resources.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 31d6ddac..9f390057 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -17,7 +17,8 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) +#include "linuxfixes.h" #include #include #include From bf8d258489e0305c0843f7ddbdc1604a968103f4 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 21:59:44 +0100 Subject: [PATCH 16/99] Update VehicleData.cpp --- src/Network/VehicleData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 7113c05a..8471e4fe 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -66,7 +66,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); From c26d3595c8cdc4089b1b95a47d2608ab26666fb0 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:05:40 +0100 Subject: [PATCH 17/99] Update Options.h --- include/Options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Options.h b/include/Options.h index 255a4ab5..5a57a0f8 100644 --- a/include/Options.h +++ b/include/Options.h @@ -5,7 +5,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; From 45dee97b31e75adf98d0254d85644930d4a35c93 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:07:34 +0100 Subject: [PATCH 18/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 9e051c84..2269e73a 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -196,7 +196,7 @@ void LegitimacyCheck() { std::string CheckVer(const std::string& dir) { #if defined(_WIN32) std::string temp, Path = dir + "\\integrity.json"; -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) std::string temp, Path = dir + "/integrity.json"; #endif std::ifstream f(Path.c_str(), std::ios::binary); From cde7a42ddc0548261463223c7e13d41301d614c3 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:12:20 +0100 Subject: [PATCH 19/99] fixes --- src/GameStart.cpp | 6 +++--- src/Security/BeamNG.cpp | 6 +++--- src/Startup.cpp | 12 ++++++------ src/main.cpp | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 509fd2e0..44a88712 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -9,7 +9,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "vdf_parser.hpp" #include #include @@ -61,7 +61,7 @@ std::string GetGamePath() { Path += Ver + "\\"; return Path; } -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) std::string GetGamePath() { // Right now only steam is supported struct passwd* pw = getpwuid(getuid()); @@ -103,7 +103,7 @@ void StartGame(std::string Dir) { std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); } -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) void StartGame(std::string Dir) { int status; std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 2269e73a..734b4509 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -9,7 +9,7 @@ #include #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "vdf_parser.hpp" #include #include @@ -37,7 +37,7 @@ void lowExit(int code) { std::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 } @@ -178,7 +178,7 @@ void LegitimacyCheck() { K3.clear(); Result.clear(); RegCloseKey(hKey); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) struct passwd* pw = getpwuid(getuid()); std::string homeDir = pw->pw_dir; // Right now only steam is supported diff --git a/src/Startup.cpp b/src/Startup.cpp index 577f7581..b662db57 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -14,7 +14,7 @@ #include #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include #endif #include "Http.h" @@ -76,7 +76,7 @@ Version::Version(const std::array& v) std::string GetEN() { #if defined(_WIN32) return "BeamMP-Launcher.exe"; -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) return "BeamMP-Launcher"; #endif } @@ -120,7 +120,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++) { @@ -151,7 +151,7 @@ void URelaunch() { void CheckName() { #if defined(_WIN32) std::string DN = GetEN(), CDir = 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) { @@ -237,7 +237,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()); @@ -324,7 +324,7 @@ void PreGame(const std::string& GamePath) { } #if defined(_WIN32) std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)"); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) // Linux version of the game cant handle mods with uppercase names std::string ZipPath(GetGamePath() + R"(mods/multiplayer/beammp.zip)"); #endif diff --git a/src/main.cpp b/src/main.cpp index e7e7048b..ef8f1d26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,7 +27,7 @@ Options options; int main(int argc, const char** argv) try { #if defined(_WIN32) system("cls"); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) system("clear"); #endif From 8039c44d6f816f859a1cac91e243ab5b0692bbe6 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:18:52 +0100 Subject: [PATCH 20/99] Update GameStart.cpp --- src/GameStart.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 44a88712..f7b702ff 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -105,6 +105,7 @@ void StartGame(std::string Dir) { } #elif defined(__linux__) || defined(__APPLE__) void StartGame(std::string Dir) { + extern char **environ; int status; std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); std::vector argv; From 94bb7366453ca4f40125f8bbfd237964dfde0306 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:29:27 +0100 Subject: [PATCH 21/99] force to arm64 --- .github/workflows/cmake-macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index cff7810a..e1c1fd62 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -18,7 +18,7 @@ jobs: uses: lukka/run-vcpkg@v7 id: runvcpkg with: - vcpkgArguments: 'zlib nlohmann-json openssl cpp-httplib[openssl]' + vcpkgArguments: 'zlib:arm64-osx nlohmann-json:arm64-osx openssl:arm64-osx cpp-httplib[openssl]:arm64-osx' vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg' vcpkgGitCommitId: '40616a5e954f7be1077ef37db3fbddbd5dcd1ca6' @@ -28,7 +28,7 @@ jobs: - 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' + 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 @@ -39,4 +39,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: BeamMP-Launcher - path: ${{github.workspace}}/build-macos/BeamMP-Launcher + path: ${{github.workspace}}/build-macos/BeamMP-Launcher \ No newline at end of file From 2bca0067f45ec11cc97628c05973b955f1eb5b7c Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:47:02 +0100 Subject: [PATCH 22/99] verify runnner arch --- .github/workflows/cmake-macos.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index e1c1fd62..72bc87f1 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -10,6 +10,9 @@ jobs: runs-on: macos-latest steps: + - name: Check system architecture + run: uname -m + - uses: actions/checkout@v2 with: submodules: 'true' From e674c160b987764d8aea7bb7b674ec4c8c4158b0 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:52:53 +0100 Subject: [PATCH 23/99] force arm64 --- .github/workflows/cmake-macos.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index 72bc87f1..b5e506ec 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -10,9 +10,6 @@ jobs: runs-on: macos-latest steps: - - name: Check system architecture - run: uname -m - - uses: actions/checkout@v2 with: submodules: 'true' @@ -21,7 +18,7 @@ jobs: uses: lukka/run-vcpkg@v7 id: runvcpkg with: - vcpkgArguments: 'zlib:arm64-osx nlohmann-json:arm64-osx openssl:arm64-osx cpp-httplib[openssl]:arm64-osx' + vcpkgArguments: 'zlib nlohmann-json openssl cpp-httplib[openssl]' vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg' vcpkgGitCommitId: '40616a5e954f7be1077ef37db3fbddbd5dcd1ca6' @@ -31,7 +28,7 @@ jobs: - 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 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake' - name: Build working-directory: ${{github.workspace}}/build-macos From f28172e3a92b08fc62a0fb8556a54c18cf2ff66b Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 22:58:18 +0100 Subject: [PATCH 24/99] force arm64 --- .github/workflows/cmake-macos.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index b5e506ec..6efce071 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -18,7 +18,7 @@ jobs: uses: lukka/run-vcpkg@v7 id: runvcpkg with: - vcpkgArguments: 'zlib nlohmann-json openssl cpp-httplib[openssl]' + 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' @@ -28,7 +28,11 @@ jobs: - 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' + 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 From 56f4e850af8b4e33ffa710775cd63ff1bd278c84 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 23:01:33 +0100 Subject: [PATCH 25/99] force arm64 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c7c924e..805f10e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ if (WIN32) STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) elseif(APPLE) - set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for MacOS" FORCE) + set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "Build architectures for MacOS" FORCE) endif(WIN32) set(CMAKE_CXX_STANDARD 20) From 4ae22914691b541db91511100bbf3a99bb7de5f2 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 7 Nov 2024 23:28:07 +0100 Subject: [PATCH 26/99] fixes --- .github/workflows/cmake-macos.yml | 46 +++++++++++++++++++++++++++++++ .gitignore | 4 +++ CMakeLists.txt | 7 +++++ include/Options.h | 2 +- src/GameStart.cpp | 12 ++++++-- src/Network/Core.cpp | 25 ++++++++--------- src/Network/DNS.cpp | 2 +- src/Network/GlobalHandler.cpp | 2 +- src/Network/Resources.cpp | 3 +- src/Network/VehicleData.cpp | 4 +-- src/Network/VehicleEvent.cpp | 3 +- src/Startup.cpp | 12 ++++---- src/main.cpp | 2 +- 13 files changed, 94 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/cmake-macos.yml diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml new file mode 100644 index 00000000..6efce071 --- /dev/null +++ b/.github/workflows/cmake-macos.yml @@ -0,0 +1,46 @@ +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: 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 \ No newline at end of file diff --git a/.gitignore b/.gitignore index d1128670..dd8d15ba 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ bin/ compile_commands.json key out/ +build/ +.vscode/ +vcpkg/ +vcpkg_installed/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ad74591e..805f10e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ if (WIN32) message(STATUS "MSVC -> forcing use of statically-linked runtime.") STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) +elseif(APPLE) + set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "Build architectures for MacOS" FORCE) endif(WIN32) set(CMAKE_CXX_STANDARD 20) @@ -32,6 +34,11 @@ elseif (LINUX) find_package(OpenSSL REQUIRED) target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) +elseif(APPLE) + find_package(ZLIB REQUIRED) + find_package(OpenSSL REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE + ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) else(WIN32) #MINGW add_definitions("-D_WIN32_WINNT=0x0600") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s --static") diff --git a/include/Options.h b/include/Options.h index 255a4ab5..5a57a0f8 100644 --- a/include/Options.h +++ b/include/Options.h @@ -5,7 +5,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; diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 194d13b9..f7b702ff 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -9,7 +9,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "vdf_parser.hpp" #include #include @@ -61,7 +61,7 @@ std::string GetGamePath() { Path += Ver + "\\"; return Path; } -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) std::string GetGamePath() { // Right now only steam is supported struct passwd* pw = getpwuid(getuid()); @@ -103,8 +103,9 @@ void StartGame(std::string Dir) { std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); } -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) void StartGame(std::string Dir) { + extern char **environ; int status; std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); std::vector argv; @@ -132,6 +133,11 @@ void StartGame(std::string Dir) { std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); } + +#elif defined(__APPLE__) +void StartGame(std::string Dir) { + error("Please launch the game manually for now"); +} #endif void InitGame(const std::string& Dir) { diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 6202c372..ea5cf4ee 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -13,7 +13,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include #include #include @@ -22,6 +22,7 @@ #include #include #include +#include "linuxfixes.h" #endif #include "Logger.h" @@ -372,21 +373,19 @@ int Handle(EXCEPTION_POINTERS* ep) { [[noreturn]] void CoreNetwork() { while (true) { -#if not defined(__MINGW32__) +#if defined(_WIN32) __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 (const std::exception& e) { + except("(Core) Exception: " + std::string(e.what())); + } catch (...) { + except("(Core) Unknown exception"); + } #endif - std::this_thread::sleep_for(std::chrono::seconds(1)); } -} +} \ No newline at end of file diff --git a/src/Network/DNS.cpp b/src/Network/DNS.cpp index d28b829f..9c77c356 100644 --- a/src/Network/DNS.cpp +++ b/src/Network/DNS.cpp @@ -10,7 +10,7 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp index cde06848..07854a58 100644 --- a/src/Network/GlobalHandler.cpp +++ b/src/Network/GlobalHandler.cpp @@ -11,7 +11,7 @@ #if defined(_WIN32) #include #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 31d6ddac..9f390057 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -17,7 +17,8 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) +#include "linuxfixes.h" #include #include #include diff --git a/src/Network/VehicleData.cpp b/src/Network/VehicleData.cpp index 860724ce..8471e4fe 100644 --- a/src/Network/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -11,7 +11,7 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include "linuxfixes.h" #include #include @@ -66,7 +66,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); diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index cc70ef6f..abb34ef8 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -14,7 +14,8 @@ #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) +#include "linuxfixes.h" #include #include #include diff --git a/src/Startup.cpp b/src/Startup.cpp index 577f7581..b662db57 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -14,7 +14,7 @@ #include #if defined(_WIN32) #include -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include #endif #include "Http.h" @@ -76,7 +76,7 @@ Version::Version(const std::array& v) std::string GetEN() { #if defined(_WIN32) return "BeamMP-Launcher.exe"; -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) return "BeamMP-Launcher"; #endif } @@ -120,7 +120,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++) { @@ -151,7 +151,7 @@ void URelaunch() { void CheckName() { #if defined(_WIN32) std::string DN = GetEN(), CDir = 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) { @@ -237,7 +237,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()); @@ -324,7 +324,7 @@ void PreGame(const std::string& GamePath) { } #if defined(_WIN32) std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)"); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) // Linux version of the game cant handle mods with uppercase names std::string ZipPath(GetGamePath() + R"(mods/multiplayer/beammp.zip)"); #endif diff --git a/src/main.cpp b/src/main.cpp index e7e7048b..ef8f1d26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,7 +27,7 @@ Options options; int main(int argc, const char** argv) try { #if defined(_WIN32) system("cls"); -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) system("clear"); #endif From a6779ed8810d01907b285ee24fd8bb91e44d0469 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 09:25:55 +0100 Subject: [PATCH 27/99] fix game path research on macos --- .gitignore | 7 +- src/Security/BeamNG.cpp | 138 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index dd8d15ba..7b4996a6 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,9 @@ out/ build/ .vscode/ vcpkg/ -vcpkg_installed/ \ No newline at end of file +vcpkg_installed/ +CMakeFiles/ +cmake_install.cmake +CMakeCache.txt +Makefile +BeamMP-Launcher \ No newline at end of file diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 734b4509..dca0c569 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -15,6 +15,9 @@ #include #include #endif +#if defined(__APPLE__) +#include +#endif #include "Logger.h" #include #include @@ -158,6 +161,37 @@ void FileList(std::vector& a, const std::string& Path) { } } } + +std::string ToLower(const std::string& str) { + std::string lowerStr = str; + std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); + return lowerStr; +} + +// Fonction pour obtenir les correspondances de lecteurs dans une "bottle" +std::map GetDriveMappings(const std::string& bottlePath) { + std::map driveMappings; + std::string dosDevicesPath = bottlePath + "/dosdevices/"; + + std::cout << "[INFO] Checking drive mappings in: " << dosDevicesPath << std::endl; + + if (std::filesystem::exists(dosDevicesPath)) { + for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { + if (entry.is_symlink()) { + std::string driveName = ToLower(entry.path().filename().string()); + // Supprimer les deux-points des noms de lecteurs + driveName.erase(std::remove(driveName.begin(), driveName.end(), ':'), driveName.end()); + std::string macPath = std::filesystem::read_symlink(entry.path()).string(); + driveMappings[driveName] = macPath; + std::cout << "[INFO] Drive " << driveName << " maps to " << macPath << std::endl; + } + } + } else { + std::cerr << "[ERROR] dosdevices directory not found for the specified bottle." << std::endl; + } + return driveMappings; +} + void LegitimacyCheck() { #if defined(_WIN32) std::string Result; @@ -178,7 +212,7 @@ void LegitimacyCheck() { K3.clear(); Result.clear(); RegCloseKey(hKey); -#elif defined(__linux__) || defined(__APPLE__) +#elif defined(__linux__) struct passwd* pw = getpwuid(getuid()); std::string homeDir = pw->pw_dir; // Right now only steam is supported @@ -191,6 +225,108 @@ void LegitimacyCheck() { break; } } +#elif defined(__APPLE__) +struct passwd* pw = getpwuid(getuid()); + std::string homeDir = pw->pw_dir; + std::string crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles/"; + std::cout << "[INFO] Crossover bottles path: " << crossoverBottlesPath << std::endl; + + for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { + if (bottle.is_directory()) { + std::cout << "[INFO] Checking bottle: " << bottle.path().filename().string() << std::endl; + + // Obtenir les correspondances de lecteurs pour cette bottle + auto driveMappings = GetDriveMappings(bottle.path().string()); + + // Chemin du fichier libraryfolders.vdf + std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + std::ifstream libraryFile(libraryFilePath); + + if (libraryFile.is_open()) { + std::string line; + while (std::getline(libraryFile, line)) { + if (line.find("\"path\"") != std::string::npos) { + // Trouver les positions des guillemets + size_t firstQuote = line.find("\"", 0); + size_t secondQuote = line.find("\"", firstQuote + 1); + size_t thirdQuote = line.find("\"", secondQuote + 1); + size_t fourthQuote = line.find("\"", thirdQuote + 1); + + if (thirdQuote != std::string::npos && fourthQuote != std::string::npos) { + // Extraire la valeur entre le troisième et le quatrième guillemet + std::string path = line.substr(thirdQuote + 1, fourthQuote - thirdQuote - 1); + + std::cout << "[INFO] Found Steam library path: " << path << std::endl; + + // Extraction de la lettre de lecteur + std::string driveLetter = path.substr(0, path.find(":")); + // Convertir en minuscules et supprimer les deux-points + driveLetter = ToLower(driveLetter); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + info("Drive letter: " + driveLetter); + + if (driveMappings.find(driveLetter) != driveMappings.end()) { + // Obtenir le chemin de base du mapping + std::string basePath = driveMappings[driveLetter]; + // Retirer la barre oblique de fin si nécessaire + if (!basePath.empty() && basePath.back() == '/') + { + basePath.pop_back(); + } + info("Base path for drive " + driveLetter + ": " + basePath); + // std::filesystem::path convertedPath = basePath; + // std::string convertedPath = basePath; + // info("Converted path: " + convertedPath.string()); + + + // Extraire le chemin additionnel en sautant les deux premiers caractères (par exemple, "C:") + std::string additionalPath = path.substr(2); + info("Additional path: " + additionalPath); + + // Remplacer les backslashes par des slashes pour une compatibilité Unix + std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); + info("Additional path after replace: " + additionalPath); + + // Supprimer la barre oblique initiale si elle existe + if (!additionalPath.empty() && additionalPath.front() == '/') + { + additionalPath.erase(0, 1); + } + info("Additional path: " + additionalPath); + + // Ajouter le chemin additionnel + std::string fullPath = basePath + additionalPath; + info("Full path: " + fullPath); + + //convertir en std::filesystem::path + std::filesystem::path convertedPath = fullPath; + + info("Converted path after append: " + convertedPath.string()); + + // Chemin complet vers BeamNG.drive + std::filesystem::path beamngPath = convertedPath / "steamapps/common/BeamNG.drive"; + info("beamngPath: " + beamngPath.string()); + + std::cout << "[INFO] Checking for BeamNG.drive in: " << beamngPath.string() << std::endl; + + // Vérifier l'existence du dossier BeamNG.drive + if (std::filesystem::exists(beamngPath)) { + std::cout << "[SUCCESS] BeamNG.drive found in bottle '" << bottle.path().filename().string() << "' at: " << beamngPath.string() << std::endl; + return; + } + } else { + std::cout << "[WARN] Drive letter " << driveLetter << " not found in mappings." << std::endl; + } + } + } + } + libraryFile.close(); + } else { + std::cerr << "[ERROR] Failed to open libraryfolders.vdf in bottle '" << bottle.path().filename().string() << "'" << std::endl; + } + } + } + std::cerr << "[FAILURE] Failed to find BeamNG.drive installation in any CrossOver bottle." << std::endl; #endif } std::string CheckVer(const std::string& dir) { From fd3dcf7a787bdc53fe8a724f15c8cc5c215c82ef Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 11:27:14 +0100 Subject: [PATCH 28/99] working --- include/Security/Init.h | 4 ++++ src/GameStart.cpp | 27 ++++++++++++++++++++++++--- src/Security/BeamNG.cpp | 21 ++++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/Security/Init.h b/include/Security/Init.h index 06dbf36a..c4286562 100644 --- a/include/Security/Init.h +++ b/include/Security/Init.h @@ -11,5 +11,9 @@ void PreGame(const std::string& GamePath); std::string CheckVer(const std::string& path); void InitGame(const std::string& Dir); std::string GetGameDir(); +#if defined(__APPLE__) +std::string GetBottlePath(); +std::string GetBottleName(); +#endif void LegitimacyCheck(); void CheckLocalKey(); \ No newline at end of file diff --git a/src/GameStart.cpp b/src/GameStart.cpp index f7b702ff..aa2c23bc 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -61,7 +61,7 @@ std::string GetGamePath() { Path += Ver + "\\"; return Path; } -#elif defined(__linux__) || defined(__APPLE__) +#elif defined(__linux__) std::string GetGamePath() { // Right now only steam is supported struct passwd* pw = getpwuid(getuid()); @@ -73,6 +73,12 @@ std::string GetGamePath() { Path += Ver + "/"; return Path; } +#elif defined(__APPLE__) +std::string GetGamePath() { + std::string BootlePath = GetBottlePath(); + std::string Path = BootlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; + return Path; +} #endif #if defined(_WIN32) @@ -103,7 +109,7 @@ void StartGame(std::string Dir) { std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); } -#elif defined(__linux__) || defined(__APPLE__) +#elif defined(__linux__) void StartGame(std::string Dir) { extern char **environ; int status; @@ -136,7 +142,22 @@ void StartGame(std::string Dir) { #elif defined(__APPLE__) void StartGame(std::string Dir) { - error("Please launch the game manually for now"); + // Game Path: /Volumes/Enzo Fournet/MacOS/SteamLibrary/steamapps/common/BeamNG.drive + std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; + info("Lancement du jeu..."); + info("Exécutable: " + executable); + std::string bootleName = GetBottleName(); + info("Bottle: " + bootleName); + std::string command = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine --bottle '" + bootleName + "' '" + executable + "'"; + info("Commande: " + command); + int result = system(command.c_str()); + if (result != 0) { + error("Échec du lancement du jeu ! Le lanceur va se fermer bientôt."); + return; + } else { + info("Jeu lancé !"); + // Attendre que le processus du jeu se termine si nécessaire + } } #endif diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index dca0c569..2d6b7dce 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -28,6 +28,7 @@ int TraceBack = 0; std::string GameDir; +std::string BoottlePath; void lowExit(int code) { TraceBack = 0; @@ -37,11 +38,23 @@ void lowExit(int code) { exit(2); } +#if defined(__APPLE__) +std::string GetBottlePath() { + return BoottlePath; +} + +std::string GetBottleName() { + return BoottlePath.substr(BoottlePath.find_last_of('/') + 1); +} +#endif + std::string GetGameDir() { #if defined(_WIN32) return GameDir.substr(0, GameDir.find_last_of('\\')); -#elif defined(__linux__) || defined(__APPLE__) +#elif defined(__linux__) return GameDir.substr(0, GameDir.find_last_of('/')); +#elif defined(__APPLE__) + return GameDir; #endif } #ifdef _WIN32 @@ -308,10 +321,16 @@ struct passwd* pw = getpwuid(getuid()); info("beamngPath: " + beamngPath.string()); std::cout << "[INFO] Checking for BeamNG.drive in: " << beamngPath.string() << std::endl; + info("Checking for BeamNG.drive in: " + beamngPath.string()); // Vérifier l'existence du dossier BeamNG.drive if (std::filesystem::exists(beamngPath)) { + info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); std::cout << "[SUCCESS] BeamNG.drive found in bottle '" << bottle.path().filename().string() << "' at: " << beamngPath.string() << std::endl; + GameDir = beamngPath.string(); + BoottlePath = bottle.path().string(); + info("GameDir: " + GameDir); + info("BoottlePath: " + BoottlePath); return; } } else { From 46eeeb4d4b8481e1d088a84a4ac66ebef2426b3f Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 14:27:25 +0100 Subject: [PATCH 29/99] fix mac os build warn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```bash Book • ➜ ~/GithubRepo/BeamMP-Launcher git:(ghcw-session-d22d) ✗ cmake --build . --config $BUILD_TYPE [ 5%] Building CXX object CMakeFiles/Launcher.dir/src/GameStart.cpp.o In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/GameStart.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:43: warning: 'codecvt_utf8' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/codecvt:194:28: note: 'codecvt_utf8' has been explicitly marked deprecated here 194 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/GameStart.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:22: warning: 'wstring_convert>' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/locale:3114:28: note: 'wstring_convert>' has been explicitly marked deprecated here 3114 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ 2 warnings generated. [ 11%] Building CXX object CMakeFiles/Launcher.dir/src/Security/BeamNG.cpp.o In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/Security/BeamNG.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:43: warning: 'codecvt_utf8' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/codecvt:194:28: note: 'codecvt_utf8' has been explicitly marked deprecated here 194 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/Security/BeamNG.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:22: warning: 'wstring_convert>' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/locale:3114:28: note: 'wstring_convert>' has been explicitly marked deprecated here 3114 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ 2 warnings generated. [ 17%] Linking CXX executable BeamMP-Launcher ld: warning: ignoring duplicate libraries: 'vcpkg_installed/arm64-osx/lib/libz.a' [100%] Built target Launcher Book • ➜ ~/GithubRepo/BeamMP-Launcher git:(ghcw-session-d22d) ✗ Book • ➜ ~/GithubRepo/BeamMP-Launcher git:(ghcw-session-d22d) ✗ cmake --build . --config $BUILD_TYPE [ 5%] Building CXX object CMakeFiles/Launcher.dir/src/GameStart.cpp.o In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/GameStart.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:43: warning: 'codecvt_utf8' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/codecvt:194:28: note: 'codecvt_utf8' has been explicitly marked deprecated here 194 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/GameStart.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:22: warning: 'wstring_convert>' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/locale:3114:28: note: 'wstring_convert>' has been explicitly marked deprecated here 3114 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ 2 warnings generated. [ 11%] Building CXX object CMakeFiles/Launcher.dir/src/Security/BeamNG.cpp.o In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/Security/BeamNG.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:43: warning: 'codecvt_utf8' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/codecvt:194:28: note: 'codecvt_utf8' has been explicitly marked deprecated here 194 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ In file included from /Users/enzofournet/GithubRepo/BeamMP-Launcher/src/Security/BeamNG.cpp:13: /Users/enzofournet/GithubRepo/BeamMP-Launcher/include/vdf_parser.hpp:134:22: warning: 'wstring_convert>' is deprecated [-Wdeprecated-declarations] 134 | std::wstring_convert> conv1; | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/locale:3114:28: note: 'wstring_convert>' has been explicitly marked deprecated here 3114 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:1022:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 1022 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__config:995:49: note: expanded from macro '_LIBCPP_DEPRECATED' 995 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ 2 warnings generated. [ 17%] Linking CXX executable BeamMP-Launcher ld: warning: ignoring duplicate libraries: 'vcpkg_installed/arm64-osx/lib/libz.a' [100%] Built target Launcher Book • ➜ ~/GithubRepo/BeamMP-Launcher git:(ghcw-session-d22d) ✗ ``` --- include/vdf_parser.hpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/include/vdf_parser.hpp b/include/vdf_parser.hpp index 23af579d..545f4298 100644 --- a/include/vdf_parser.hpp +++ b/include/vdf_parser.hpp @@ -44,6 +44,10 @@ // internal #include +#if defined(__APPLE__) +#include +#endif + //VS < 2015 has only partial C++11 support #if defined(_MSC_VER) && _MSC_VER < 1900 #ifndef CONSTEXPR @@ -117,12 +121,31 @@ namespace tyti deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} ~deletable_facet() {} }; - + + #if !defined(__APPLE__) inline std::string string_converter(const std::wstring& w) //todo: use us-locale { std::wstring_convert>> conv1; return conv1.to_bytes(w); } + #else + inline std::string string_converter(const std::wstring& w) + { + if (w.empty()) return std::string(); + + // Calcul de la taille nécessaire + size_t size = std::wcstombs(nullptr, w.c_str(), 0); + if (size == static_cast(-1)) { + // Gestion de l'erreur de conversion + return ""; + } + + std::string s(size, '\0'); + std::wcstombs(&s[0], w.c_str(), size); + return s; + } + #endif + /////////////////////////////////////////////////////////////////////////// // Writer helper functions From c116cb249381fbdc9256f5f9b943e5bc142372df Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 14:30:31 +0100 Subject: [PATCH 30/99] ready --- src/GameStart.cpp | 48 +++++++++++++++++++++++++++++--------- src/Security/BeamNG.cpp | 51 ++++++----------------------------------- src/main.cpp | 3 +++ 3 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index aa2c23bc..9672dce5 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -77,6 +77,9 @@ std::string GetGamePath() { std::string GetGamePath() { std::string BootlePath = GetBottlePath(); std::string Path = BootlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; + std::string Ver = CheckVer(GetGameDir()); + Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1)); + Path += Ver + "/"; return Path; } #endif @@ -142,22 +145,45 @@ void StartGame(std::string Dir) { #elif defined(__APPLE__) void StartGame(std::string Dir) { - // Game Path: /Volumes/Enzo Fournet/MacOS/SteamLibrary/steamapps/common/BeamNG.drive + extern char **environ; + int status; + std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; - info("Lancement du jeu..."); - info("Exécutable: " + executable); - std::string bootleName = GetBottleName(); - info("Bottle: " + bootleName); - std::string command = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine --bottle '" + bootleName + "' '" + executable + "'"; - info("Commande: " + command); - int result = system(command.c_str()); + + std::string wineExecutable = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine"; + std::string bottleName = GetBottleName(); + + std::vector argv; + argv.push_back(wineExecutable.c_str()); + argv.push_back("--bottle"); + argv.push_back(bottleName.c_str()); + argv.push_back(executable.c_str()); + + for (int i = 0; i < options.game_arguments_length; i++) { + argv.push_back(options.game_arguments[i]); + info("options.game_arguments[i]"); + info(options.game_arguments[i]); + } + argv.push_back(nullptr); + + pid_t pid; + posix_spawn_file_actions_t spawn_actions; + posix_spawn_file_actions_init(&spawn_actions); + posix_spawn_file_actions_addclose(&spawn_actions, STDOUT_FILENO); + posix_spawn_file_actions_addclose(&spawn_actions, STDERR_FILENO); + + int result = posix_spawn(&pid, wineExecutable.c_str(), &spawn_actions, nullptr, const_cast(argv.data()), environ); + if (result != 0) { - error("Échec du lancement du jeu ! Le lanceur va se fermer bientôt."); + error("Failed to Launch the game! launcher closing soon"); return; } else { - info("Jeu lancé !"); - // Attendre que le processus du jeu se termine si nécessaire + waitpid(pid, &status, 0); + info("Game Closed! launcher closing soon"); } + + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(2); } #endif diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 2d6b7dce..9643a132 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -186,8 +186,6 @@ std::map GetDriveMappings(const std::string& bottlePat std::map driveMappings; std::string dosDevicesPath = bottlePath + "/dosdevices/"; - std::cout << "[INFO] Checking drive mappings in: " << dosDevicesPath << std::endl; - if (std::filesystem::exists(dosDevicesPath)) { for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { @@ -196,7 +194,6 @@ std::map GetDriveMappings(const std::string& bottlePat driveName.erase(std::remove(driveName.begin(), driveName.end(), ':'), driveName.end()); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); driveMappings[driveName] = macPath; - std::cout << "[INFO] Drive " << driveName << " maps to " << macPath << std::endl; } } } else { @@ -242,16 +239,14 @@ void LegitimacyCheck() { struct passwd* pw = getpwuid(getuid()); std::string homeDir = pw->pw_dir; std::string crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles/"; - std::cout << "[INFO] Crossover bottles path: " << crossoverBottlesPath << std::endl; + info("Crossover bottles path: " + crossoverBottlesPath); for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { if (bottle.is_directory()) { - std::cout << "[INFO] Checking bottle: " << bottle.path().filename().string() << std::endl; + info("Checking bottle: " + bottle.path().filename().string()); - // Obtenir les correspondances de lecteurs pour cette bottle auto driveMappings = GetDriveMappings(bottle.path().string()); - // Chemin du fichier libraryfolders.vdf std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; std::ifstream libraryFile(libraryFilePath); @@ -259,74 +254,42 @@ struct passwd* pw = getpwuid(getuid()); std::string line; while (std::getline(libraryFile, line)) { if (line.find("\"path\"") != std::string::npos) { - // Trouver les positions des guillemets size_t firstQuote = line.find("\"", 0); size_t secondQuote = line.find("\"", firstQuote + 1); size_t thirdQuote = line.find("\"", secondQuote + 1); size_t fourthQuote = line.find("\"", thirdQuote + 1); if (thirdQuote != std::string::npos && fourthQuote != std::string::npos) { - // Extraire la valeur entre le troisième et le quatrième guillemet std::string path = line.substr(thirdQuote + 1, fourthQuote - thirdQuote - 1); - std::cout << "[INFO] Found Steam library path: " << path << std::endl; + info("Found Steam library path: " + path); - // Extraction de la lettre de lecteur std::string driveLetter = path.substr(0, path.find(":")); - // Convertir en minuscules et supprimer les deux-points driveLetter = ToLower(driveLetter); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - info("Drive letter: " + driveLetter); if (driveMappings.find(driveLetter) != driveMappings.end()) { - // Obtenir le chemin de base du mapping std::string basePath = driveMappings[driveLetter]; - // Retirer la barre oblique de fin si nécessaire if (!basePath.empty() && basePath.back() == '/') { basePath.pop_back(); - } - info("Base path for drive " + driveLetter + ": " + basePath); - // std::filesystem::path convertedPath = basePath; - // std::string convertedPath = basePath; - // info("Converted path: " + convertedPath.string()); - - - // Extraire le chemin additionnel en sautant les deux premiers caractères (par exemple, "C:") + } std::string additionalPath = path.substr(2); - info("Additional path: " + additionalPath); - - // Remplacer les backslashes par des slashes pour une compatibilité Unix std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - info("Additional path after replace: " + additionalPath); - // Supprimer la barre oblique initiale si elle existe if (!additionalPath.empty() && additionalPath.front() == '/') { additionalPath.erase(0, 1); } - info("Additional path: " + additionalPath); - // Ajouter le chemin additionnel std::string fullPath = basePath + additionalPath; - info("Full path: " + fullPath); - - //convertir en std::filesystem::path std::filesystem::path convertedPath = fullPath; - - info("Converted path after append: " + convertedPath.string()); - - // Chemin complet vers BeamNG.drive std::filesystem::path beamngPath = convertedPath / "steamapps/common/BeamNG.drive"; - info("beamngPath: " + beamngPath.string()); - std::cout << "[INFO] Checking for BeamNG.drive in: " << beamngPath.string() << std::endl; info("Checking for BeamNG.drive in: " + beamngPath.string()); - // Vérifier l'existence du dossier BeamNG.drive if (std::filesystem::exists(beamngPath)) { info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); - std::cout << "[SUCCESS] BeamNG.drive found in bottle '" << bottle.path().filename().string() << "' at: " << beamngPath.string() << std::endl; GameDir = beamngPath.string(); BoottlePath = bottle.path().string(); info("GameDir: " + GameDir); @@ -334,18 +297,18 @@ struct passwd* pw = getpwuid(getuid()); return; } } else { - std::cout << "[WARN] Drive letter " << driveLetter << " not found in mappings." << std::endl; + warn("Drive letter " + driveLetter + " not found in mappings."); } } } } libraryFile.close(); } else { - std::cerr << "[ERROR] Failed to open libraryfolders.vdf in bottle '" << bottle.path().filename().string() << "'" << std::endl; + error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); } } } - std::cerr << "[FAILURE] Failed to find BeamNG.drive installation in any CrossOver bottle." << std::endl; + error("Failed to find BeamNG.drive installation in any CrossOver bottle."); #endif } std::string CheckVer(const std::string& dir) { diff --git a/src/main.cpp b/src/main.cpp index ef8f1d26..b87fe878 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,9 @@ int main(int argc, const char** argv) try { InitLauncher(); info("IMPORTANT: You MUST keep this window open to play BeamMP!"); + #if defined(__APPLE__) + info("BeamMP is supported on MacOS through CrossOver. Please make sure you have it installed."); + #endif try { LegitimacyCheck(); From abc401f6e4b8aa81be439282e7605c951854420e Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 14:42:51 +0100 Subject: [PATCH 31/99] fix windows build --- src/Security/BeamNG.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 9643a132..ed435f20 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -9,6 +9,7 @@ #include #if defined(_WIN32) #include +#include #elif defined(__linux__) || defined(__APPLE__) #include "vdf_parser.hpp" #include From 5a825d0e092a5d4471e7674761f5667cba900b80 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 8 Nov 2024 14:44:14 +0100 Subject: [PATCH 32/99] fix windows build one method was only for mac --- src/Security/BeamNG.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index ed435f20..56238dc6 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -9,7 +9,6 @@ #include #if defined(_WIN32) #include -#include #elif defined(__linux__) || defined(__APPLE__) #include "vdf_parser.hpp" #include @@ -182,6 +181,7 @@ std::string ToLower(const std::string& str) { return lowerStr; } +#if defined(__APPLE__) // Fonction pour obtenir les correspondances de lecteurs dans une "bottle" std::map GetDriveMappings(const std::string& bottlePath) { std::map driveMappings; @@ -202,6 +202,7 @@ std::map GetDriveMappings(const std::string& bottlePat } return driveMappings; } +#endif void LegitimacyCheck() { #if defined(_WIN32) From 3434ecebe38d5465d10e08ac0836e601b3ffe824 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Mon, 11 Nov 2024 21:30:31 +0100 Subject: [PATCH 33/99] We should stop the app if we don't find any beamng installation --- src/Security/BeamNG.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 56238dc6..aee50d37 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -311,6 +311,7 @@ struct passwd* pw = getpwuid(getuid()); } } error("Failed to find BeamNG.drive installation in any CrossOver bottle."); + exit(1); #endif } std::string CheckVer(const std::string& dir) { From 1c16b31e44e339c627ba02ca1a5d401a7cdb9cb1 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 08:59:25 +0100 Subject: [PATCH 34/99] We must need to be sure that the path we get is absolut to be able to retrieve game anywhere --- src/Security/BeamNG.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index aee50d37..4723c574 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -182,7 +182,6 @@ std::string ToLower(const std::string& str) { } #if defined(__APPLE__) -// Fonction pour obtenir les correspondances de lecteurs dans une "bottle" std::map GetDriveMappings(const std::string& bottlePath) { std::map driveMappings; std::string dosDevicesPath = bottlePath + "/dosdevices/"; @@ -191,9 +190,11 @@ std::map GetDriveMappings(const std::string& bottlePat for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { std::string driveName = ToLower(entry.path().filename().string()); - // Supprimer les deux-points des noms de lecteurs driveName.erase(std::remove(driveName.begin(), driveName.end(), ':'), driveName.end()); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); + if (!std::filesystem::path(macPath).is_absolute()) { + macPath = dosDevicesPath + macPath; + } driveMappings[driveName] = macPath; } } From f574798571c3f30aa7260b368e82e1c46db1a89c Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:37:17 +0100 Subject: [PATCH 35/99] Condition on include --- src/Network/Core.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 6141c707..bb3befde 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -22,6 +22,9 @@ #include #include #include +#endif + +#if defined(__APPLE__) #include "linuxfixes.h" #endif From 57d2f094948120f72e908ec7991af6420b9d654b Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:40:19 +0100 Subject: [PATCH 36/99] moved toLower to Utils.h --- include/Utils.h | 11 +++++++++-- src/Security/BeamNG.cpp | 11 +++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/Utils.h b/include/Utils.h index 0342c11b..3a3c2e64 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace Utils { inline std::vector Split(const std::string& String, const std::string& delimiter) { @@ -16,5 +17,11 @@ namespace Utils { if (!s.empty()) Val.push_back(s); return Val; - }; -}; \ No newline at end of file + } + + inline std::string ToLower(const std::string& str) { + std::string lowerStr = str; + std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); + return lowerStr; + } +} \ No newline at end of file diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 4723c574..0224cbe1 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -16,6 +16,7 @@ #include #endif #if defined(__APPLE__) +#include "Utils.h" #include #endif #include "Logger.h" @@ -175,12 +176,6 @@ void FileList(std::vector& a, const std::string& Path) { } } -std::string ToLower(const std::string& str) { - std::string lowerStr = str; - std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); - return lowerStr; -} - #if defined(__APPLE__) std::map GetDriveMappings(const std::string& bottlePath) { std::map driveMappings; @@ -189,7 +184,7 @@ std::map GetDriveMappings(const std::string& bottlePat if (std::filesystem::exists(dosDevicesPath)) { for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { - std::string driveName = ToLower(entry.path().filename().string()); + std::string driveName = Utils::ToLower(entry.path().filename().string()); driveName.erase(std::remove(driveName.begin(), driveName.end(), ':'), driveName.end()); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); if (!std::filesystem::path(macPath).is_absolute()) { @@ -268,7 +263,7 @@ struct passwd* pw = getpwuid(getuid()); info("Found Steam library path: " + path); std::string driveLetter = path.substr(0, path.find(":")); - driveLetter = ToLower(driveLetter); + driveLetter = Utils::ToLower(driveLetter); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); if (driveMappings.find(driveLetter) != driveMappings.end()) { From a96014afceb0d678613adb1a2dd9feabfd8785a6 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:42:05 +0100 Subject: [PATCH 37/99] correct BoottlePath -> BottlePath --- src/Security/BeamNG.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 0224cbe1..bb5099cf 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -29,7 +29,7 @@ int TraceBack = 0; std::string GameDir; -std::string BoottlePath; +std::string BottlePath; void lowExit(int code) { TraceBack = 0; @@ -41,11 +41,11 @@ void lowExit(int code) { #if defined(__APPLE__) std::string GetBottlePath() { - return BoottlePath; + return BottlePath; } std::string GetBottleName() { - return BoottlePath.substr(BoottlePath.find_last_of('/') + 1); + return BottlePath.substr(BottlePath.find_last_of('/') + 1); } #endif @@ -289,9 +289,9 @@ struct passwd* pw = getpwuid(getuid()); if (std::filesystem::exists(beamngPath)) { info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); GameDir = beamngPath.string(); - BoottlePath = bottle.path().string(); + BottlePath = bottle.path().string(); info("GameDir: " + GameDir); - info("BoottlePath: " + BoottlePath); + info("BottlePath: " + BottlePath); return; } } else { From 1afe74e227e8deb8c8d9a089a162a82160608fe3 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:44:32 +0100 Subject: [PATCH 38/99] BootlePath -> BotlePath --- src/GameStart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 9672dce5..5f77ef5f 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -75,8 +75,8 @@ std::string GetGamePath() { } #elif defined(__APPLE__) std::string GetGamePath() { - std::string BootlePath = GetBottlePath(); - std::string Path = BootlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; + std::string BotlePath = GetBottlePath(); + std::string Path = BotlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; std::string Ver = CheckVer(GetGameDir()); Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1)); Path += Ver + "/"; From 131114f59b3ae26f8fc45ad9d612ca0e36723d03 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:47:00 +0100 Subject: [PATCH 39/99] no more edition on vdf_parser --- include/vdf_parser.hpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/include/vdf_parser.hpp b/include/vdf_parser.hpp index 545f4298..4951f325 100644 --- a/include/vdf_parser.hpp +++ b/include/vdf_parser.hpp @@ -44,10 +44,6 @@ // internal #include -#if defined(__APPLE__) -#include -#endif - //VS < 2015 has only partial C++11 support #if defined(_MSC_VER) && _MSC_VER < 1900 #ifndef CONSTEXPR @@ -122,29 +118,11 @@ namespace tyti ~deletable_facet() {} }; - #if !defined(__APPLE__) inline std::string string_converter(const std::wstring& w) //todo: use us-locale { std::wstring_convert>> conv1; return conv1.to_bytes(w); } - #else - inline std::string string_converter(const std::wstring& w) - { - if (w.empty()) return std::string(); - - // Calcul de la taille nécessaire - size_t size = std::wcstombs(nullptr, w.c_str(), 0); - if (size == static_cast(-1)) { - // Gestion de l'erreur de conversion - return ""; - } - - std::string s(size, '\0'); - std::wcstombs(&s[0], w.c_str(), size); - return s; - } - #endif /////////////////////////////////////////////////////////////////////////// From 3693b592dcbd8795a6edd10e1b51363c58b4cef2 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:47:34 +0100 Subject: [PATCH 40/99] Update vdf_parser.hpp --- include/vdf_parser.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/vdf_parser.hpp b/include/vdf_parser.hpp index 4951f325..baf1dcce 100644 --- a/include/vdf_parser.hpp +++ b/include/vdf_parser.hpp @@ -117,13 +117,11 @@ namespace tyti deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} ~deletable_facet() {} }; - inline std::string string_converter(const std::wstring& w) //todo: use us-locale { std::wstring_convert>> conv1; return conv1.to_bytes(w); } - /////////////////////////////////////////////////////////////////////////// // Writer helper functions From a4a26fd43da3bd35feaf184cb681e381b2258b37 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:49:05 +0100 Subject: [PATCH 41/99] add nullptdr at the end of the args --- src/GameStart.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 5f77ef5f..79471bb7 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -158,6 +158,7 @@ void StartGame(std::string Dir) { argv.push_back("--bottle"); argv.push_back(bottleName.c_str()); argv.push_back(executable.c_str()); + argv.push_back(nullptr); for (int i = 0; i < options.game_arguments_length; i++) { argv.push_back(options.game_arguments[i]); From 06b697cd54c8e3d96879b1f23b53f4fcb1c37c36 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:51:35 +0100 Subject: [PATCH 42/99] remove useless logs --- src/GameStart.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 79471bb7..24d5e386 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -162,8 +162,6 @@ void StartGame(std::string Dir) { for (int i = 0; i < options.game_arguments_length; i++) { argv.push_back(options.game_arguments[i]); - info("options.game_arguments[i]"); - info(options.game_arguments[i]); } argv.push_back(nullptr); From 7facffcb12d10df82d58f3a28c66c9b45066ec34 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:52:24 +0100 Subject: [PATCH 43/99] fix wrong log level --- src/Network/Core.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index bb3befde..be4c22a8 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -384,9 +384,9 @@ int Handle(EXCEPTION_POINTERS* ep) { try { CoreMain(); } catch (const std::exception& e) { - except("(Core) Exception: " + std::string(e.what())); + error("(Core) Exception: " + std::string(e.what())); } catch (...) { - except("(Core) Unknown exception"); + error("(Core) Unknown exception"); } #endif std::this_thread::sleep_for(std::chrono::seconds(1)); From 87ddb95a2cd7fba5b4ce6562d3a483d38c397f70 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 14:53:35 +0100 Subject: [PATCH 44/99] include algorithm anyway --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index bb5099cf..d21692c5 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -17,8 +17,8 @@ #endif #if defined(__APPLE__) #include "Utils.h" -#include #endif +#include #include "Logger.h" #include #include From bf24e5342365509b2e876e92131cfc992eee0553 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 15:04:32 +0100 Subject: [PATCH 45/99] GetBottleName using filesystem --- src/Security/BeamNG.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index d21692c5..ddb2ced1 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -45,7 +45,8 @@ std::string GetBottlePath() { } std::string GetBottleName() { - return BottlePath.substr(BottlePath.find_last_of('/') + 1); + std::filesystem::path bottlePath(BottlePath); + return bottlePath.filename().string(); } #endif From c738795683a80f11c04a6f2aa51c33496bcfbace Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 15:30:00 +0100 Subject: [PATCH 46/99] fix environ --- src/GameStart.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 24d5e386..001ee17e 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -114,7 +114,6 @@ void StartGame(std::string Dir) { } #elif defined(__linux__) void StartGame(std::string Dir) { - extern char **environ; int status; std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64"); std::vector argv; From 6ff5e1f0eb7fb6cba181357a0fe50e66ecab5c94 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 15:55:04 +0100 Subject: [PATCH 47/99] using existing vdf parser --- .DS_Store | Bin 0 -> 8196 bytes src/Security/BeamNG.cpp | 97 ++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 54 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..bb5b2291ebd95b4d01fa5cb4a4cb4d7a8fd9ea55 GIT binary patch literal 8196 zcmeHMT~6CT5T12{8lVDHqzWNb^#!oh8<_l5LZVXDif15BLMcwt5`yTP-+KqHfO?o7 zrcdoRvn#T@PWo6??X0ys&U(I?*>8WWafryY=Yv;7dqmViWx2D7W=Y}aTx%t9JRpK7ZNC^qLa~+~)Kc(P~(QRm* z)0p1STRNa)+|Pk6=mYw%BlH8d=9Y)v{XH7r63#ic&`N^Mo}74A)~FAkmsHXq)Fk)| zqTO6*BGxgi^EZoGh%zrC)GoAG_X;CAg&$_-2ER*O+2UDfMSS0TQEpKO99b(J@yrZm zuyhx*ED`wF4G;TTMmnrT{WXf(_je2o$2?o%kFmbLCL+77GjD!GKAs301$da#fQBIh z$wj37G+rIT-iR(joOto0S%xbyZxK%X`M8~$zfj@ z_4nx-=Ci;ku42~2p0ByT&~$rbg2+eUfLG9g%(%b)m$1-$8O6Ba+05u8Ea7|!Bj%GO zI2*P-OuXxcF)QM6F$$9+02F=yTOPDk24V&pwquX;|K95F|1nH|D+9{FKg57(cHei~ z7?8`YYeVB)J4HQ1<-&TEl>$K{={TgMpw_dir; std::string crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles/"; info("Crossover bottles path: " + crossoverBottlesPath); for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { - if (bottle.is_directory()) { - info("Checking bottle: " + bottle.path().filename().string()); - - auto driveMappings = GetDriveMappings(bottle.path().string()); + if (!bottle.is_directory()) continue; - std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; - std::ifstream libraryFile(libraryFilePath); + info("Checking bottle: " + bottle.path().filename().string()); + auto driveMappings = GetDriveMappings(bottle.path().string()); - if (libraryFile.is_open()) { - std::string line; - while (std::getline(libraryFile, line)) { - if (line.find("\"path\"") != std::string::npos) { - size_t firstQuote = line.find("\"", 0); - size_t secondQuote = line.find("\"", firstQuote + 1); - size_t thirdQuote = line.find("\"", secondQuote + 1); - size_t fourthQuote = line.find("\"", thirdQuote + 1); + std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + std::ifstream libraryFile(libraryFilePath); + if (!libraryFile.is_open()) { + error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); + continue; + } + + auto root = tyti::vdf::read(libraryFile); + libraryFile.close(); - if (thirdQuote != std::string::npos && fourthQuote != std::string::npos) { - std::string path = line.substr(thirdQuote + 1, fourthQuote - thirdQuote - 1); + for (const auto& [key, folderInfo] : root.childs) { + auto pathIter = folderInfo->attribs.find("path"); + if (pathIter == folderInfo->attribs.end()) continue; - info("Found Steam library path: " + path); + std::string path = pathIter->second; + info("Found Steam library path: " + path); - std::string driveLetter = path.substr(0, path.find(":")); - driveLetter = Utils::ToLower(driveLetter); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - if (driveMappings.find(driveLetter) != driveMappings.end()) { - std::string basePath = driveMappings[driveLetter]; - if (!basePath.empty() && basePath.back() == '/') - { - basePath.pop_back(); - } - std::string additionalPath = path.substr(2); - std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); + if (driveMappings.find(driveLetter) == driveMappings.end()) { + warn("Drive letter " + driveLetter + " not found in mappings."); + continue; + } - if (!additionalPath.empty() && additionalPath.front() == '/') - { - additionalPath.erase(0, 1); - } + std::string basePath = driveMappings[driveLetter]; + if (!basePath.empty() && basePath.back() == '/') { + basePath.pop_back(); + } - std::string fullPath = basePath + additionalPath; - std::filesystem::path convertedPath = fullPath; - std::filesystem::path beamngPath = convertedPath / "steamapps/common/BeamNG.drive"; + std::string additionalPath = path.substr(2); + std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); + if (!additionalPath.empty() && additionalPath.front() == '/') { + additionalPath.erase(0, 1); + } - info("Checking for BeamNG.drive in: " + beamngPath.string()); + std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; + info("Checking for BeamNG.drive in: " + beamngPath.string()); - if (std::filesystem::exists(beamngPath)) { - info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); - GameDir = beamngPath.string(); - BottlePath = bottle.path().string(); - info("GameDir: " + GameDir); - info("BottlePath: " + BottlePath); - return; - } - } else { - warn("Drive letter " + driveLetter + " not found in mappings."); - } - } - } - } - libraryFile.close(); - } else { - error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); + if (std::filesystem::exists(beamngPath)) { + info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); + GameDir = beamngPath.string(); + BottlePath = bottle.path().string(); + info("GameDir: " + GameDir); + info("BottlePath: " + BottlePath); + return; } } } From 649d46c77ae8d5635b51fd26ad7986df5fa75446 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:13:57 +0100 Subject: [PATCH 48/99] fix include linux fix for MacOS --- include/Network/network.hpp | 4 ++++ src/Network/Core.cpp | 4 ---- src/Network/Resources.cpp | 1 - src/Network/VehicleEvent.cpp | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/Network/network.hpp b/include/Network/network.hpp index 287c6259..4f412442 100644 --- a/include/Network/network.hpp +++ b/include/Network/network.hpp @@ -16,6 +16,10 @@ #include #endif +#ifdef __APPLE__ +#include "linuxfixes.h" +#endif + void NetReset(); extern bool Dev; extern int ping; diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index be4c22a8..ca2131d7 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -24,10 +24,6 @@ #include #endif -#if defined(__APPLE__) -#include "linuxfixes.h" -#endif - #include "Logger.h" #include "Startup.h" #include diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 9f390057..ee079bab 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -18,7 +18,6 @@ #if defined(_WIN32) #include #elif defined(__linux__) || defined(__APPLE__) -#include "linuxfixes.h" #include #include #include diff --git a/src/Network/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp index abb34ef8..8a2f8c8b 100644 --- a/src/Network/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -15,7 +15,6 @@ #if defined(_WIN32) #include #elif defined(__linux__) || defined(__APPLE__) -#include "linuxfixes.h" #include #include #include From 4c23152832e114f8494861964070747a9dd6abdc Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:16:13 +0100 Subject: [PATCH 49/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 7cfcd8b8..59cce633 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -195,7 +195,7 @@ std::map GetDriveMappings(const std::string& bottlePat } } } else { - std::cerr << "[ERROR] dosdevices directory not found for the specified bottle." << std::endl; + error("Failed to find dosdevices directory for bottle '" + bottlePath + "'"); } return driveMappings; } @@ -296,7 +296,7 @@ void LegitimacyCheck() { } } } - error("Failed to find BeamNG.drive installation in any CrossOver bottle."); + error("Failed to find BeamNG.drive installation in any CrossOver bottle. Make sure BeamNG.drive is installed in a CrossOver bottle."); exit(1); #endif } From 02ba91fedda3b7ba5024a3801e469a5511b7a86e Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:16:43 +0100 Subject: [PATCH 50/99] Update main.cpp --- src/main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b87fe878..ef8f1d26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,9 +46,6 @@ int main(int argc, const char** argv) try { InitLauncher(); info("IMPORTANT: You MUST keep this window open to play BeamMP!"); - #if defined(__APPLE__) - info("BeamMP is supported on MacOS through CrossOver. Please make sure you have it installed."); - #endif try { LegitimacyCheck(); From e5ec812435ce093571de080e51a047f45ea663ee Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:17:53 +0100 Subject: [PATCH 51/99] Revert "add nullptdr at the end of the args" This reverts commit a4a26fd43da3bd35feaf184cb681e381b2258b37. --- src/GameStart.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 001ee17e..cef159e7 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -157,7 +157,6 @@ void StartGame(std::string Dir) { argv.push_back("--bottle"); argv.push_back(bottleName.c_str()); argv.push_back(executable.c_str()); - argv.push_back(nullptr); for (int i = 0; i < options.game_arguments_length; i++) { argv.push_back(options.game_arguments[i]); From 40e62aad1086dc185af9414489d6ffd45a6bc951 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:18:51 +0100 Subject: [PATCH 52/99] Update vdf_parser.hpp --- include/vdf_parser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/vdf_parser.hpp b/include/vdf_parser.hpp index baf1dcce..291c7205 100644 --- a/include/vdf_parser.hpp +++ b/include/vdf_parser.hpp @@ -117,6 +117,7 @@ namespace tyti deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} ~deletable_facet() {} }; + inline std::string string_converter(const std::wstring& w) //todo: use us-locale { std::wstring_convert>> conv1; From 99d3a79038e0d7a7bd1872019e10f5cceeb23955 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 13 Nov 2024 16:19:10 +0100 Subject: [PATCH 53/99] Update vdf_parser.hpp --- include/vdf_parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vdf_parser.hpp b/include/vdf_parser.hpp index 291c7205..23af579d 100644 --- a/include/vdf_parser.hpp +++ b/include/vdf_parser.hpp @@ -117,7 +117,7 @@ namespace tyti deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} ~deletable_facet() {} }; - + inline std::string string_converter(const std::wstring& w) //todo: use us-locale { std::wstring_convert>> conv1; From 50b31ef9513dbe134a1260960b4dbba575d01a9b Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:54:47 +0100 Subject: [PATCH 54/99] Improve MacOS support via CrossOver --- include/Options.h | 1 + include/Utils.h | 14 +++++ src/GameStart.cpp | 14 ++++- src/Network/Resources.cpp | 1 + src/Options.cpp | 6 ++ src/Security/BeamNG.cpp | 127 ++++++++++++++++++++++++-------------- 6 files changed, 114 insertions(+), 49 deletions(-) diff --git a/include/Options.h b/include/Options.h index 5a57a0f8..c85df7d1 100644 --- a/include/Options.h +++ b/include/Options.h @@ -15,6 +15,7 @@ struct Options { bool no_launch = false; const char **game_arguments = nullptr; int game_arguments_length = 0; + std::string bottle; const char** argv = nullptr; int argc = 0; }; diff --git a/include/Utils.h b/include/Utils.h index 3a3c2e64..4c2c4438 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -24,4 +24,18 @@ namespace Utils { std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); return lowerStr; } + + inline std::pair runCommand(const char* cmd) { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("failed to run popen()"); + } + while (fgets(buffer.data(), static_cast(buffer.size()), pipe.get()) != nullptr) { + result += buffer.data(); + } + int returnCode = pclose(pipe.release()); + return { result, returnCode }; + } } \ No newline at end of file diff --git a/src/GameStart.cpp b/src/GameStart.cpp index cef159e7..0ce11819 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -24,6 +24,7 @@ #include #include #include "Options.h" +#include "Utils.h" unsigned long GamePID = 0; #if defined(_WIN32) @@ -75,8 +76,8 @@ std::string GetGamePath() { } #elif defined(__APPLE__) std::string GetGamePath() { - std::string BotlePath = GetBottlePath(); - std::string Path = BotlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; + std::string BottlePath = GetBottlePath(); + std::string Path = BottlePath + "/drive_c/users/crossover/AppData/Local/BeamNG.drive/"; std::string Ver = CheckVer(GetGameDir()); Ver = Ver.substr(0, Ver.find('.', Ver.find('.') + 1)); Path += Ver + "/"; @@ -148,8 +149,15 @@ void StartGame(std::string Dir) { int status; std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; + std::pair sharedCmd = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist | grep \"SharedSupport\" | sed -E 's|.*\"(.*SharedSupport/).*\".*|\\1|' | head -n 1"); + std::string sharedPath = sharedCmd.first; + int statusCode = sharedCmd.second; + if (statusCode != 0) { + error("Failed to detect SharedSupport folder, please make sure CrossOver is installed."); + exit(1); + } - std::string wineExecutable = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine"; + std::string wineExecutable = sharedPath + "CrossOver/CrossOver-Hosted Application/wine"; std::string bottleName = GetBottleName(); std::vector argv; diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index ee079bab..0b1f212d 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "hashpp.h" diff --git a/src/Options.cpp b/src/Options.cpp index 1389570a..75ac5931 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -80,6 +80,9 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_download = true; options.no_launch = true; options.no_update = true; + } else if (argument == "--bottle") { + options.bottle = argv[i + 1]; + i++; } else if (argument == "--" || argument == "--game") { options.game_arguments = &argv[i + 1]; options.game_arguments_length = argc - i - 1; @@ -95,6 +98,9 @@ void InitOptions(int argc, const char *argv[], Options &options) { "\t--no-update Skip applying launcher updates (you must update manually)\n" "\t--no-launch Skip launching the game (you must launch the game manually)\n" "\t--dev Developer mode, same as --verbose --no-download --no-launch --no-update\n" + #if defined(__APPLE__) + "\t--bottle Name of the Bottle where the game is located in\n" + #endif "\t--game Passes ALL following arguments to the game, see also `--`\n" << std::flush; exit(0); diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 59cce633..7b688c7d 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -17,6 +17,13 @@ #endif #if defined(__APPLE__) #include "Utils.h" +#include "Options.h" +#include +#include +#include +#include +#include +#include #endif #include #include "Logger.h" @@ -236,68 +243,96 @@ void LegitimacyCheck() { } #elif defined(__APPLE__) - struct passwd* pw = getpwuid(getuid()); - std::string homeDir = pw->pw_dir; - std::string crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles/"; +struct passwd* pw = getpwuid(getuid()); + if (options.bottle.empty()) { + error("Crossover Bottle not set, please set it with the --bottle flag."); + exit(1); + } + + std::pair bottlesCmd = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist BottleDir"); + std::string crossoverBottlesPath = bottlesCmd.first; + int statusCode = bottlesCmd.second; + + if (statusCode != 0) { + error("Failed to detect Crossover, please make sure you have it installed."); + exit(1); + } + crossoverBottlesPath.pop_back(); // Remove newline character from the path + crossoverBottlesPath += "/"; info("Crossover bottles path: " + crossoverBottlesPath); - for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { - if (!bottle.is_directory()) continue; + std::string bottlePath = crossoverBottlesPath + options.bottle; + if (std::filesystem::exists(bottlePath)) { + info("Checking bottle: " + options.bottle); - info("Checking bottle: " + bottle.path().filename().string()); - auto driveMappings = GetDriveMappings(bottle.path().string()); + auto driveMappings = GetDriveMappings(bottlePath); - std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + std::string libraryFilePath = bottlePath + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; std::ifstream libraryFile(libraryFilePath); - if (!libraryFile.is_open()) { - error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); - continue; - } - - auto root = tyti::vdf::read(libraryFile); - libraryFile.close(); - for (const auto& [key, folderInfo] : root.childs) { - auto pathIter = folderInfo->attribs.find("path"); - if (pathIter == folderInfo->attribs.end()) continue; + if (libraryFile.is_open()) { + std::string line; + while (std::getline(libraryFile, line)) { + if (line.find("\"path\"") != std::string::npos) { + size_t firstQuote = line.find("\"", 0); + size_t secondQuote = line.find("\"", firstQuote + 1); + size_t thirdQuote = line.find("\"", secondQuote + 1); + size_t fourthQuote = line.find("\"", thirdQuote + 1); - std::string path = pathIter->second; - info("Found Steam library path: " + path); + if (thirdQuote != std::string::npos && fourthQuote != std::string::npos) { + std::string path = line.substr(thirdQuote + 1, fourthQuote - thirdQuote - 1); - std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + info("Found Steam library path: " + path); - if (driveMappings.find(driveLetter) == driveMappings.end()) { - warn("Drive letter " + driveLetter + " not found in mappings."); - continue; - } + std::string driveLetter = path.substr(0, path.find(":")); + driveLetter = Utils::ToLower(driveLetter); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - std::string basePath = driveMappings[driveLetter]; - if (!basePath.empty() && basePath.back() == '/') { - basePath.pop_back(); - } + if (driveMappings.find(driveLetter) != driveMappings.end()) { + std::string basePath = driveMappings[driveLetter]; + if (!basePath.empty() && basePath.back() == '/') + { + basePath.pop_back(); + } + std::string additionalPath = path.substr(2); + std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - std::string additionalPath = path.substr(2); - std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - if (!additionalPath.empty() && additionalPath.front() == '/') { - additionalPath.erase(0, 1); - } + if (!additionalPath.empty() && additionalPath.front() == '/') + { + additionalPath.erase(0, 1); + } + + std::string fullPath = basePath + additionalPath; + std::filesystem::path convertedPath = fullPath; + std::filesystem::path beamngPath = convertedPath / "steamapps/common/BeamNG.drive"; - std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; - info("Checking for BeamNG.drive in: " + beamngPath.string()); + info("Checking for BeamNG.drive in: " + beamngPath.string()); - if (std::filesystem::exists(beamngPath)) { - info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); - GameDir = beamngPath.string(); - BottlePath = bottle.path().string(); - info("GameDir: " + GameDir); - info("BottlePath: " + BottlePath); - return; + if (std::filesystem::exists(beamngPath)) { + info("BeamNG.drive found at: " + beamngPath.string()); + GameDir = beamngPath.string(); + BottlePath = bottlePath; + info("GameDir: " + GameDir); + info("BottlePath: " + BottlePath); + return; + } + } else { + warn("Drive letter " + driveLetter + " not found in mappings."); + } + } + } } + libraryFile.close(); + } else { + error("Failed to open libraryfolders.vdf in bottle '" + options.bottle + "'. Please make sure Steam is installed in this bottle."); + exit(1); } + error("Failed to find BeamNG.drive"); + exit(1); + } else { + error("Bottle " + options.bottle + " doesn't exist"); + exit(1); } - error("Failed to find BeamNG.drive installation in any CrossOver bottle. Make sure BeamNG.drive is installed in a CrossOver bottle."); - exit(1); #endif } std::string CheckVer(const std::string& dir) { From 4d5f5387f9ed1a6e8f81266b4bf4527bfcfa9f38 Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:41:37 +0100 Subject: [PATCH 55/99] Forgot to include memory --- include/Utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Utils.h b/include/Utils.h index 4c2c4438..b35fa729 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -2,6 +2,7 @@ #include #include #include +#include namespace Utils { inline std::vector Split(const std::string& String, const std::string& delimiter) { From 05eeb63ad175cdc5ccd7fdfdff4daa82eda5b8e0 Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:03:20 +0100 Subject: [PATCH 56/99] Exclude the windows and linux builds --- include/Utils.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/include/Utils.h b/include/Utils.h index b35fa729..f575148a 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -2,7 +2,6 @@ #include #include #include -#include namespace Utils { inline std::vector Split(const std::string& String, const std::string& delimiter) { @@ -26,17 +25,19 @@ namespace Utils { return lowerStr; } - inline std::pair runCommand(const char* cmd) { - std::array buffer; - std::string result; - std::unique_ptr pipe(popen(cmd, "r"), pclose); - if (!pipe) { - throw std::runtime_error("failed to run popen()"); + #if defined(__APPLE__) + inline std::pair runCommand(const char* cmd) { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("failed to run popen()"); + } + while (fgets(buffer.data(), static_cast(buffer.size()), pipe.get()) != nullptr) { + result += buffer.data(); + } + int returnCode = pclose(pipe.release()); + return { result, returnCode }; } - while (fgets(buffer.data(), static_cast(buffer.size()), pipe.get()) != nullptr) { - result += buffer.data(); - } - int returnCode = pclose(pipe.release()); - return { result, returnCode }; - } + #endif } \ No newline at end of file From 50d854dbe8a79ffbeea386dd4405be2981184646 Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:00:42 +0100 Subject: [PATCH 57/99] Readd bottle scanning if the --bottle argument isn't set --- .gitignore | 3 +- src/Security/BeamNG.cpp | 199 +++++++++++++++++++++++++--------------- 2 files changed, 129 insertions(+), 73 deletions(-) diff --git a/.gitignore b/.gitignore index 7b4996a6..2f495436 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ CMakeFiles/ cmake_install.cmake CMakeCache.txt Makefile -BeamMP-Launcher \ No newline at end of file +BeamMP-Launcher +.DS_Store \ No newline at end of file diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 7b688c7d..a634fc11 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -243,96 +243,151 @@ void LegitimacyCheck() { } #elif defined(__APPLE__) -struct passwd* pw = getpwuid(getuid()); - if (options.bottle.empty()) { - error("Crossover Bottle not set, please set it with the --bottle flag."); - exit(1); - } + struct passwd* pw = getpwuid(getuid()); + std::string homeDir = pw->pw_dir; + std::string bottlePath; std::pair bottlesCmd = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist BottleDir"); std::string crossoverBottlesPath = bottlesCmd.first; int statusCode = bottlesCmd.second; if (statusCode != 0) { - error("Failed to detect Crossover, please make sure you have it installed."); - exit(1); + std::filesystem::path bottlesFolder(homeDir + "/Library/Application Support/CrossOver/Bottles"); + if (std::filesystem::exists(bottlesFolder)) { + info("Using the default bottles path"); + crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles"; + } else { + error("Failed to detect Crossover, please make sure you have it installed."); + exit(1); + } + } else { + crossoverBottlesPath.pop_back(); // Remove newline character from the path + crossoverBottlesPath += "/"; } - crossoverBottlesPath.pop_back(); // Remove newline character from the path - crossoverBottlesPath += "/"; + info("Crossover bottles path: " + crossoverBottlesPath); - std::string bottlePath = crossoverBottlesPath + options.bottle; - if (std::filesystem::exists(bottlePath)) { - info("Checking bottle: " + options.bottle); + if (!empty(options.bottle)) { + std::filesystem::path bottleFolder(crossoverBottlesPath + options.bottle); + if (std::filesystem::exists(bottleFolder)) { + info("Checking bottle: " + bottleFolder.filename().string()); + auto driveMappings = GetDriveMappings(bottleFolder.string()); + + std::string libraryFilePath = bottleFolder.string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + std::ifstream libraryFile(libraryFilePath); + if (!libraryFile.is_open()) { + error("Failed to open libraryfolders.vdf in bottle '" + bottleFolder.filename().string() + "'"); + exit(1); + } - auto driveMappings = GetDriveMappings(bottlePath); + auto root = tyti::vdf::read(libraryFile); + libraryFile.close(); - std::string libraryFilePath = bottlePath + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; - std::ifstream libraryFile(libraryFilePath); + for (const auto& [key, folderInfo] : root.childs) { + auto pathIter = folderInfo->attribs.find("path"); + if (pathIter == folderInfo->attribs.end()) + continue; - if (libraryFile.is_open()) { - std::string line; - while (std::getline(libraryFile, line)) { - if (line.find("\"path\"") != std::string::npos) { - size_t firstQuote = line.find("\"", 0); - size_t secondQuote = line.find("\"", firstQuote + 1); - size_t thirdQuote = line.find("\"", secondQuote + 1); - size_t fourthQuote = line.find("\"", thirdQuote + 1); - - if (thirdQuote != std::string::npos && fourthQuote != std::string::npos) { - std::string path = line.substr(thirdQuote + 1, fourthQuote - thirdQuote - 1); - - info("Found Steam library path: " + path); - - std::string driveLetter = path.substr(0, path.find(":")); - driveLetter = Utils::ToLower(driveLetter); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - - if (driveMappings.find(driveLetter) != driveMappings.end()) { - std::string basePath = driveMappings[driveLetter]; - if (!basePath.empty() && basePath.back() == '/') - { - basePath.pop_back(); - } - std::string additionalPath = path.substr(2); - std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - - if (!additionalPath.empty() && additionalPath.front() == '/') - { - additionalPath.erase(0, 1); - } - - std::string fullPath = basePath + additionalPath; - std::filesystem::path convertedPath = fullPath; - std::filesystem::path beamngPath = convertedPath / "steamapps/common/BeamNG.drive"; - - info("Checking for BeamNG.drive in: " + beamngPath.string()); - - if (std::filesystem::exists(beamngPath)) { - info("BeamNG.drive found at: " + beamngPath.string()); - GameDir = beamngPath.string(); - BottlePath = bottlePath; - info("GameDir: " + GameDir); - info("BottlePath: " + BottlePath); - return; - } - } else { - warn("Drive letter " + driveLetter + " not found in mappings."); - } - } + std::string path = pathIter->second; + info("Found Steam library path: " + path); + + std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + + if (driveMappings.find(driveLetter) == driveMappings.end()) { + warn("Drive letter " + driveLetter + " not found in mappings."); + continue; + } + + std::string basePath = driveMappings[driveLetter]; + if (!basePath.empty() && basePath.back() == '/') { + basePath.pop_back(); + } + + std::string additionalPath = path.substr(2); + std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); + if (!additionalPath.empty() && additionalPath.front() == '/') { + additionalPath.erase(0, 1); + } + + std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; + info("Checking for BeamNG.drive in: " + beamngPath.string()); + + if (std::filesystem::exists(beamngPath)) { + info("BeamNG.drive found in bottle '" + bottleFolder.filename().string() + "' at: " + beamngPath.string()); + GameDir = beamngPath.string(); + BottlePath = bottleFolder.string(); + info("GameDir: " + GameDir); + info("BottlePath: " + BottlePath); + return; } } - libraryFile.close(); } else { - error("Failed to open libraryfolders.vdf in bottle '" + options.bottle + "'. Please make sure Steam is installed in this bottle."); + error("Bottle '" + options.bottle + "' doesn't exist"); exit(1); } - error("Failed to find BeamNG.drive"); - exit(1); - } else { - error("Bottle " + options.bottle + " doesn't exist"); - exit(1); } + for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { + if (!bottle.is_directory()) + continue; + + info("Checking bottle: " + bottle.path().filename().string()); + auto driveMappings = GetDriveMappings(bottle.path().string()); + + std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + std::ifstream libraryFile(libraryFilePath); + if (!libraryFile.is_open()) { + error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); + continue; + } + + auto root = tyti::vdf::read(libraryFile); + libraryFile.close(); + + for (const auto& [key, folderInfo] : root.childs) { + auto pathIter = folderInfo->attribs.find("path"); + if (pathIter == folderInfo->attribs.end()) + continue; + + std::string path = pathIter->second; + info("Found Steam library path: " + path); + + std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + + if (driveMappings.find(driveLetter) == driveMappings.end()) { + warn("Drive letter " + driveLetter + " not found in mappings."); + continue; + } + + std::string basePath = driveMappings[driveLetter]; + if (!basePath.empty() && basePath.back() == '/') { + basePath.pop_back(); + } + + std::string additionalPath = path.substr(2); + std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); + if (!additionalPath.empty() && additionalPath.front() == '/') { + additionalPath.erase(0, 1); + } + + std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; + info("Checking for BeamNG.drive in: " + beamngPath.string()); + + if (std::filesystem::exists(beamngPath)) { + info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); + GameDir = beamngPath.string(); + BottlePath = bottle.path().string(); + info("GameDir: " + GameDir); + info("BottlePath: " + BottlePath); + return; + } + } + } + + error("Failed to find BeamNG.drive installation in any CrossOver bottle. Make sure BeamNG.drive is installed in a CrossOver bottle, or set it with the --bottle argument."); + exit(1); + #endif } std::string CheckVer(const std::string& dir) { From e901fcb65f3952e4b369c7f8e331f1944b7a4997 Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:18:35 +0100 Subject: [PATCH 58/99] Improve the detection of the wine executable --- src/GameStart.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index 0ce11819..e0fe5f55 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -149,15 +149,18 @@ void StartGame(std::string Dir) { int status; std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; - std::pair sharedCmd = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist | grep \"SharedSupport\" | sed -E 's|.*\"(.*SharedSupport/).*\".*|\\1|' | head -n 1"); + std::pair sharedCmd = Utils::runCommand("mdfind kMDItemCFBundleIdentifier = 'com.codeweavers.CrossOver'"); std::string sharedPath = sharedCmd.first; int statusCode = sharedCmd.second; if (statusCode != 0) { error("Failed to detect SharedSupport folder, please make sure CrossOver is installed."); exit(1); + } else { + sharedPath.pop_back(); // Remove newline character from the path + sharedPath += "/"; } - std::string wineExecutable = sharedPath + "CrossOver/CrossOver-Hosted Application/wine"; + std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wine"; std::string bottleName = GetBottleName(); std::vector argv; From 1a7a7cab2829d96d2a9356d91b2baa477aed77f7 Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:48:10 +0100 Subject: [PATCH 59/99] Remove the mdfind command --- src/GameStart.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index e0fe5f55..a2e7b739 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -149,18 +149,7 @@ void StartGame(std::string Dir) { int status; std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; - std::pair sharedCmd = Utils::runCommand("mdfind kMDItemCFBundleIdentifier = 'com.codeweavers.CrossOver'"); - std::string sharedPath = sharedCmd.first; - int statusCode = sharedCmd.second; - if (statusCode != 0) { - error("Failed to detect SharedSupport folder, please make sure CrossOver is installed."); - exit(1); - } else { - sharedPath.pop_back(); // Remove newline character from the path - sharedPath += "/"; - } - - std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wine"; + std::string wineExecutable = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine"; std::string bottleName = GetBottleName(); std::vector argv; From 4a0f3509212aee7af3b03ee3b2d83114d92711b3 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:05:55 +0100 Subject: [PATCH 60/99] Delete .DS_Store --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index bb5b2291ebd95b4d01fa5cb4a4cb4d7a8fd9ea55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMT~6CT5T12{8lVDHqzWNb^#!oh8<_l5LZVXDif15BLMcwt5`yTP-+KqHfO?o7 zrcdoRvn#T@PWo6??X0ys&U(I?*>8WWafryY=Yv;7dqmViWx2D7W=Y}aTx%t9JRpK7ZNC^qLa~+~)Kc(P~(QRm* z)0p1STRNa)+|Pk6=mYw%BlH8d=9Y)v{XH7r63#ic&`N^Mo}74A)~FAkmsHXq)Fk)| zqTO6*BGxgi^EZoGh%zrC)GoAG_X;CAg&$_-2ER*O+2UDfMSS0TQEpKO99b(J@yrZm zuyhx*ED`wF4G;TTMmnrT{WXf(_je2o$2?o%kFmbLCL+77GjD!GKAs301$da#fQBIh z$wj37G+rIT-iR(joOto0S%xbyZxK%X`M8~$zfj@ z_4nx-=Ci;ku42~2p0ByT&~$rbg2+eUfLG9g%(%b)m$1-$8O6Ba+05u8Ea7|!Bj%GO zI2*P-OuXxcF)QM6F$$9+02F=yTOPDk24V&pwquX;|K95F|1nH|D+9{FKg57(cHei~ z7?8`YYeVB)J4HQ1<-&TEl>$K{={TgM Date: Fri, 15 Nov 2024 19:08:21 +0100 Subject: [PATCH 61/99] Revert "Remove the mdfind command" This reverts commit 1a7a7cab2829d96d2a9356d91b2baa477aed77f7. --- src/GameStart.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index a2e7b739..e0fe5f55 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -149,7 +149,18 @@ void StartGame(std::string Dir) { int status; std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; - std::string wineExecutable = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine"; + std::pair sharedCmd = Utils::runCommand("mdfind kMDItemCFBundleIdentifier = 'com.codeweavers.CrossOver'"); + std::string sharedPath = sharedCmd.first; + int statusCode = sharedCmd.second; + if (statusCode != 0) { + error("Failed to detect SharedSupport folder, please make sure CrossOver is installed."); + exit(1); + } else { + sharedPath.pop_back(); // Remove newline character from the path + sharedPath += "/"; + } + + std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wine"; std::string bottleName = GetBottleName(); std::vector argv; From 5eb307383a485feb6088427f7b287418c76be247 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:20:41 +0100 Subject: [PATCH 62/99] bottle option only needed on MacOS --- include/Options.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Options.h b/include/Options.h index c85df7d1..a54df2ba 100644 --- a/include/Options.h +++ b/include/Options.h @@ -15,7 +15,9 @@ struct Options { bool no_launch = false; const char **game_arguments = nullptr; int game_arguments_length = 0; +#if defined(__APPLE__) std::string bottle; +#endif const char** argv = nullptr; int argc = 0; }; From 7178d79f7ae60651678e7d295d9b2c7820cca087 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:21:54 +0100 Subject: [PATCH 63/99] fix retrive wine executable --- src/GameStart.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index e0fe5f55..cebd7385 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -156,13 +156,27 @@ void StartGame(std::string Dir) { error("Failed to detect SharedSupport folder, please make sure CrossOver is installed."); exit(1); } else { - sharedPath.pop_back(); // Remove newline character from the path + std::istringstream stream(sharedPath); + std::string line; + std::vector paths; + while (std::getline(stream, line)) { + if (line.find("CrossOver.app") != std::string::npos) { + paths.push_back(line); + } + } + if (paths.empty()) { + error("No valid CrossOver.app found."); + exit(1); + } else if (paths.size() > 1) { + debug("Multiple CrossOver.app found, using the first one."); + } + sharedPath = paths[0]; sharedPath += "/"; } - + std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wine"; std::string bottleName = GetBottleName(); - + std::vector argv; argv.push_back(wineExecutable.c_str()); argv.push_back("--bottle"); From d5251edd7590a18a7ed6fdbf829ec5a9d8393d9f Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:23:55 +0100 Subject: [PATCH 64/99] iostream not needed here --- src/Network/Resources.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 0b1f212d..833de6f8 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include From 0db93a440d5b105c384100adf58c5cad0518cf71 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:27:08 +0100 Subject: [PATCH 65/99] =?UTF-8?q?Only=20needed=20on=20=EF=A3=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Options.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Options.cpp b/src/Options.cpp index 75ac5931..03eca172 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -80,9 +80,11 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_download = true; options.no_launch = true; options.no_update = true; + #if defined(__APPLE__) } else if (argument == "--bottle") { options.bottle = argv[i + 1]; i++; + #endif } else if (argument == "--" || argument == "--game") { options.game_arguments = &argv[i + 1]; options.game_arguments_length = argc - i - 1; From bc1b97e3448b6444a0cf23ab030d0f563e71490a Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:28:30 +0100 Subject: [PATCH 66/99] Update Resources.cpp --- src/Network/Resources.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Network/Resources.cpp b/src/Network/Resources.cpp index 833de6f8..b9b28ec1 100644 --- a/src/Network/Resources.cpp +++ b/src/Network/Resources.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "hashpp.h" From 91b01bee8dfe3c936b14cc0830dc0cc0d30f9f5d Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:46:15 +0100 Subject: [PATCH 67/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index a634fc11..eb317c9d 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -304,10 +304,10 @@ void LegitimacyCheck() { basePath.pop_back(); } - std::string additionalPath = path.substr(2); - std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - if (!additionalPath.empty() && additionalPath.front() == '/') { - additionalPath.erase(0, 1); + // Normalize the path using std::filesystem + std::filesystem::path additionalPath = std::filesystem::path(path.substr(2)).make_preferred(); + if (!additionalPath.empty() && additionalPath.is_absolute()) { + additionalPath = additionalPath.relative_path(); } std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; From 47ebc7d3facd3f0875c6c10fc6447e078939a39d Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Fri, 15 Nov 2024 19:50:22 +0100 Subject: [PATCH 68/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index eb317c9d..169a4653 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -355,7 +355,7 @@ void LegitimacyCheck() { std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - if (driveMappings.find(driveLetter) == driveMappings.end()) { + if (!driveMappings.contains(driveLetter)) { warn("Drive letter " + driveLetter + " not found in mappings."); continue; } From a4c47b265d661fd61a1d35c0e1f79baa64c795fb Mon Sep 17 00:00:00 2001 From: JxxIT <110342008+JxxIT@users.noreply.github.com> Date: Sat, 16 Nov 2024 09:12:03 +0100 Subject: [PATCH 69/99] Fix wine executable with non-default bottles folder --- src/GameStart.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/GameStart.cpp b/src/GameStart.cpp index cebd7385..25e107de 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -149,6 +149,10 @@ void StartGame(std::string Dir) { int status; std::string executable = Dir + "/Bin64/BeamNG.drive.x64.exe"; + if (!std::filesystem::exists(executable)) { + error("The executable BeamNG.drive.x64.exe doesn't exist in folder: " + Dir + "/Bin64/"); + exit(1); + } std::pair sharedCmd = Utils::runCommand("mdfind kMDItemCFBundleIdentifier = 'com.codeweavers.CrossOver'"); std::string sharedPath = sharedCmd.first; int statusCode = sharedCmd.second; @@ -174,13 +178,12 @@ void StartGame(std::string Dir) { sharedPath += "/"; } - std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wine"; - std::string bottleName = GetBottleName(); - + std::string wineExecutable = sharedPath + "Contents/SharedSupport/CrossOver/bin/wine"; + std::string bottlePath = GetBottlePath(); std::vector argv; argv.push_back(wineExecutable.c_str()); argv.push_back("--bottle"); - argv.push_back(bottleName.c_str()); + argv.push_back(bottlePath.c_str()); argv.push_back(executable.c_str()); for (int i = 0; i < options.game_arguments_length; i++) { From a1bbcf54844e5812988333dd20abdd548ed56beb Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 08:59:09 +0100 Subject: [PATCH 70/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 169a4653..228da7ad 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -15,7 +15,6 @@ #include #include #endif -#if defined(__APPLE__) #include "Utils.h" #include "Options.h" #include @@ -24,7 +23,6 @@ #include #include #include -#endif #include #include "Logger.h" #include From 0b685b63603a32147f8cf54cc59ee84fa8190566 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:06:37 +0100 Subject: [PATCH 71/99] contains --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 228da7ad..140925d5 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -292,7 +292,7 @@ void LegitimacyCheck() { std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - if (driveMappings.find(driveLetter) == driveMappings.end()) { + if (!driveMappings.contains(driveLetter)) { warn("Drive letter " + driveLetter + " not found in mappings."); continue; } From 717ba0ac62b64256f1ad0921cfc6e189e699b9e7 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:06:46 +0100 Subject: [PATCH 72/99] debug log --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 140925d5..5480f3af 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -309,7 +309,7 @@ void LegitimacyCheck() { } std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; - info("Checking for BeamNG.drive in: " + beamngPath.string()); + debug("Checking for BeamNG.drive in: " + beamngPath.string()); if (std::filesystem::exists(beamngPath)) { info("BeamNG.drive found in bottle '" + bottleFolder.filename().string() + "' at: " + beamngPath.string()); From 5e702e598f7852cb363d8097ad47801db7ca414e Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:07:37 +0100 Subject: [PATCH 73/99] debug log --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 5480f3af..834a8a7a 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -348,7 +348,7 @@ void LegitimacyCheck() { continue; std::string path = pathIter->second; - info("Found Steam library path: " + path); + debug("Found Steam library path: " + path); std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); From 025a73ff567a887c2b077651f15ca16c2fb9987e Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:09:50 +0100 Subject: [PATCH 74/99] debug bottle path --- src/Security/BeamNG.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 834a8a7a..49306cf8 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -315,8 +315,7 @@ void LegitimacyCheck() { info("BeamNG.drive found in bottle '" + bottleFolder.filename().string() + "' at: " + beamngPath.string()); GameDir = beamngPath.string(); BottlePath = bottleFolder.string(); - info("GameDir: " + GameDir); - info("BottlePath: " + BottlePath); + debug("CrossOver bottle path where BeamNG.drive was found: " + BottlePath); return; } } From 19ef8adcdc33ef61bb2bf4f1f6eac80ac92b47a4 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:13:26 +0100 Subject: [PATCH 75/99] debug bottles path --- src/Security/BeamNG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 49306cf8..26f81e51 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -252,7 +252,7 @@ void LegitimacyCheck() { if (statusCode != 0) { std::filesystem::path bottlesFolder(homeDir + "/Library/Application Support/CrossOver/Bottles"); if (std::filesystem::exists(bottlesFolder)) { - info("Using the default bottles path"); + debug("Using the default Crossover bottles path"); crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles"; } else { error("Failed to detect Crossover, please make sure you have it installed."); @@ -263,7 +263,7 @@ void LegitimacyCheck() { crossoverBottlesPath += "/"; } - info("Crossover bottles path: " + crossoverBottlesPath); + debug("Crossover bottles path: " + crossoverBottlesPath); if (!empty(options.bottle)) { std::filesystem::path bottleFolder(crossoverBottlesPath + options.bottle); From db584ecf6ba9364c2f80d6af010fc04a00c65a0d Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Tue, 19 Nov 2024 09:17:40 +0100 Subject: [PATCH 76/99] try to fix __MINGW32__ --- src/Network/Core.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index ca2131d7..13a22185 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -372,7 +372,7 @@ int Handle(EXCEPTION_POINTERS* ep) { [[noreturn]] void CoreNetwork() { while (true) { -#if defined(_WIN32) +#if defined(_WIN32) && !defined(__MINGW32__) __try { CoreMain(); } __except (Handle(GetExceptionInformation())) { } @@ -384,6 +384,8 @@ int Handle(EXCEPTION_POINTERS* ep) { } catch (...) { error("(Core) Unknown exception"); } +#else + CoreMain(); #endif std::this_thread::sleep_for(std::chrono::seconds(1)); } From a93cfa04ac35e7398cea7320cd016dff8276d14a Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Thu, 21 Nov 2024 15:36:38 +0100 Subject: [PATCH 77/99] Improve code structure and adding bottle-path for non crossover users --- include/Options.h | 1 + src/Options.cpp | 19 ++- src/Security/BeamNG.cpp | 256 ++++++++++++++++++---------------------- 3 files changed, 133 insertions(+), 143 deletions(-) diff --git a/include/Options.h b/include/Options.h index a54df2ba..3279631d 100644 --- a/include/Options.h +++ b/include/Options.h @@ -17,6 +17,7 @@ struct Options { int game_arguments_length = 0; #if defined(__APPLE__) std::string bottle; + std::string bottle_path; #endif const char** argv = nullptr; int argc = 0; diff --git a/src/Options.cpp b/src/Options.cpp index 03eca172..13284e49 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -81,8 +81,20 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_launch = true; options.no_update = true; #if defined(__APPLE__) - } else if (argument == "--bottle") { - options.bottle = argv[i + 1]; + } else if (argument == "--bottle" || argument == "--bottle-path") { + // if (i + 1 >= argc) { + // std::string error_message = + // "No bottle specified, resorting to default"; + // error(error_message); + // i++; + // continue; + // } + + if (argument == "--bottle") { + options.bottle = argv[i + 1]; + } else { + options.bottle_path = argv[i + 1]; + } i++; #endif } else if (argument == "--" || argument == "--game") { @@ -101,7 +113,8 @@ void InitOptions(int argc, const char *argv[], Options &options) { "\t--no-launch Skip launching the game (you must launch the game manually)\n" "\t--dev Developer mode, same as --verbose --no-download --no-launch --no-update\n" #if defined(__APPLE__) - "\t--bottle Name of the Bottle where the game is located in\n" + "\t--bottle Name of the Bottle where the game is located in\n" + "\t--bottle-path Path to the Bottle where the game is located in\n" #endif "\t--game Passes ALL following arguments to the game, see also `--`\n" << std::flush; diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 26f81e51..ec1f5da8 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -44,17 +44,6 @@ void lowExit(int code) { exit(2); } -#if defined(__APPLE__) -std::string GetBottlePath() { - return BottlePath; -} - -std::string GetBottleName() { - std::filesystem::path bottlePath(BottlePath); - return bottlePath.filename().string(); -} -#endif - std::string GetGameDir() { #if defined(_WIN32) return GameDir.substr(0, GameDir.find_last_of('\\')); @@ -183,6 +172,16 @@ void FileList(std::vector& a, const std::string& Path) { } #if defined(__APPLE__) + +std::string GetBottlePath() { + return BottlePath; +} + +std::string GetBottleName() { + std::filesystem::path bottlePath(BottlePath); + return bottlePath.filename().string(); +} + std::map GetDriveMappings(const std::string& bottlePath) { std::map driveMappings; std::string dosDevicesPath = bottlePath + "/dosdevices/"; @@ -204,6 +203,73 @@ std::map GetDriveMappings(const std::string& bottlePat } return driveMappings; } + +bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { + // Convertir le chemin Windows en style Unix + std::string driveLetter = Utils::ToLower(libraryPath.substr(0, libraryPath.find(":"))); + driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + + if (!driveMappings.contains(driveLetter)) { + warn("Drive letter " + driveLetter + " not found in mappings."); + return false; + } + + std::string basePath = driveMappings.at(driveLetter); + + // Corriger les slashs + std::replace(basePath.begin(), basePath.end(), '\\', '/'); + + std::string cleanLibraryPath = libraryPath.substr(2); + std::replace(cleanLibraryPath.begin(), cleanLibraryPath.end(), '\\', '/'); + debug("Cleaned library path: " + cleanLibraryPath); + + // Construire le chemin complet + std::string fullPath = basePath + cleanLibraryPath + "/steamapps/common/BeamNG.drive"; + debug("Checking for BeamNG.drive at: " + fullPath); + + + // Normaliser le chemin complet + fs::path beamngPath = fullPath; + beamngPath = beamngPath.lexically_normal(); // Normalise les `../` dans le chemin + + debug("Checking for BeamNG.drive at: " + beamngPath.string()); + + if (fs::exists(beamngPath)) { + GameDir = beamngPath.string(); + info("BeamNG.drive found at: " + GameDir); + return true; + } + + return false; +} + +void ProcessBottle(const fs::path& bottlePath) { + info("Checking bottle: " + bottlePath.filename().string()); + auto driveMappings = GetDriveMappings(bottlePath.string()); + + const fs::path libraryFilePath = bottlePath / "drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; + if (!fs::exists(libraryFilePath)) { + warn("Library file not found in bottle: " + bottlePath.filename().string()); + return; + } + + std::ifstream libraryFile(libraryFilePath); + if (!libraryFile.is_open()) { + error("Failed to open libraryfolders.vdf in bottle: " + bottlePath.filename().string()); + return; + } + + auto root = tyti::vdf::read(libraryFile); + libraryFile.close(); + + for (const auto& [key, folderInfo] : root.childs) { + if (folderInfo->attribs.contains("path") && + CheckForGame(folderInfo->attribs.at("path"), driveMappings)) { + BottlePath = bottlePath.string(); + return; + } + } +} #endif void LegitimacyCheck() { @@ -241,148 +307,58 @@ void LegitimacyCheck() { } #elif defined(__APPLE__) - struct passwd* pw = getpwuid(getuid()); - std::string homeDir = pw->pw_dir; - std::string bottlePath; - - std::pair bottlesCmd = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist BottleDir"); - std::string crossoverBottlesPath = bottlesCmd.first; - int statusCode = bottlesCmd.second; - - if (statusCode != 0) { - std::filesystem::path bottlesFolder(homeDir + "/Library/Application Support/CrossOver/Bottles"); - if (std::filesystem::exists(bottlesFolder)) { - debug("Using the default Crossover bottles path"); - crossoverBottlesPath = homeDir + "/Library/Application Support/CrossOver/Bottles"; - } else { - error("Failed to detect Crossover, please make sure you have it installed."); - exit(1); - } - } else { - crossoverBottlesPath.pop_back(); // Remove newline character from the path - crossoverBottlesPath += "/"; - } - - debug("Crossover bottles path: " + crossoverBottlesPath); - - if (!empty(options.bottle)) { - std::filesystem::path bottleFolder(crossoverBottlesPath + options.bottle); - if (std::filesystem::exists(bottleFolder)) { - info("Checking bottle: " + bottleFolder.filename().string()); - auto driveMappings = GetDriveMappings(bottleFolder.string()); - - std::string libraryFilePath = bottleFolder.string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; - std::ifstream libraryFile(libraryFilePath); - if (!libraryFile.is_open()) { - error("Failed to open libraryfolders.vdf in bottle '" + bottleFolder.filename().string() + "'"); + if (empty(options.bottle_path)) { + const char* homeDir = getpwuid(getuid())->pw_dir; + std::string crossoverBottlesPath; + + auto [output, status] = Utils::runCommand("defaults read com.codeweavers.CrossOver.plist BottleDir"); + if (status != 0) { + fs::path defaultBottlesPath = fs::path(homeDir) / "Library/Application Support/CrossOver/Bottles"; + if (!fs::exists(defaultBottlesPath)) { + error("Failed to detect CrossOver installation."); exit(1); } - - auto root = tyti::vdf::read(libraryFile); - libraryFile.close(); - - for (const auto& [key, folderInfo] : root.childs) { - auto pathIter = folderInfo->attribs.find("path"); - if (pathIter == folderInfo->attribs.end()) - continue; - - std::string path = pathIter->second; - info("Found Steam library path: " + path); - - std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - - if (!driveMappings.contains(driveLetter)) { - warn("Drive letter " + driveLetter + " not found in mappings."); - continue; - } - - std::string basePath = driveMappings[driveLetter]; - if (!basePath.empty() && basePath.back() == '/') { - basePath.pop_back(); - } - - // Normalize the path using std::filesystem - std::filesystem::path additionalPath = std::filesystem::path(path.substr(2)).make_preferred(); - if (!additionalPath.empty() && additionalPath.is_absolute()) { - additionalPath = additionalPath.relative_path(); - } - - std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; - debug("Checking for BeamNG.drive in: " + beamngPath.string()); - - if (std::filesystem::exists(beamngPath)) { - info("BeamNG.drive found in bottle '" + bottleFolder.filename().string() + "' at: " + beamngPath.string()); - GameDir = beamngPath.string(); - BottlePath = bottleFolder.string(); - debug("CrossOver bottle path where BeamNG.drive was found: " + BottlePath); - return; - } - } + crossoverBottlesPath = defaultBottlesPath.string(); } else { - error("Bottle '" + options.bottle + "' doesn't exist"); - exit(1); - } - } - for (const auto& bottle : std::filesystem::directory_iterator(crossoverBottlesPath)) { - if (!bottle.is_directory()) - continue; - - info("Checking bottle: " + bottle.path().filename().string()); - auto driveMappings = GetDriveMappings(bottle.path().string()); - - std::string libraryFilePath = bottle.path().string() + "/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"; - std::ifstream libraryFile(libraryFilePath); - if (!libraryFile.is_open()) { - error("Failed to open libraryfolders.vdf in bottle '" + bottle.path().filename().string() + "'"); - continue; + crossoverBottlesPath = output; + crossoverBottlesPath.pop_back(); } - auto root = tyti::vdf::read(libraryFile); - libraryFile.close(); - - for (const auto& [key, folderInfo] : root.childs) { - auto pathIter = folderInfo->attribs.find("path"); - if (pathIter == folderInfo->attribs.end()) - continue; - - std::string path = pathIter->second; - debug("Found Steam library path: " + path); - - std::string driveLetter = Utils::ToLower(path.substr(0, path.find(":"))); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); - - if (!driveMappings.contains(driveLetter)) { - warn("Drive letter " + driveLetter + " not found in mappings."); - continue; - } + debug("Crossover bottles path: " + crossoverBottlesPath); - std::string basePath = driveMappings[driveLetter]; - if (!basePath.empty() && basePath.back() == '/') { - basePath.pop_back(); + if (empty(options.bottle)) { + for (const auto& bottle : fs::directory_iterator(crossoverBottlesPath)) { + if (bottle.is_directory()) { + ProcessBottle(bottle.path()); + if (!GameDir.empty()) { + return; + } + } } - - std::string additionalPath = path.substr(2); - std::replace(additionalPath.begin(), additionalPath.end(), '\\', '/'); - if (!additionalPath.empty() && additionalPath.front() == '/') { - additionalPath.erase(0, 1); + } else { + fs::path bottlePath = crossoverBottlesPath + "/" + options.bottle; + if (!fs::exists(bottlePath)) { + error("Bottle does not exist: " + bottlePath.string()); + exit(1); } - - std::filesystem::path beamngPath = std::filesystem::path(basePath) / additionalPath / "steamapps/common/BeamNG.drive"; - info("Checking for BeamNG.drive in: " + beamngPath.string()); - - if (std::filesystem::exists(beamngPath)) { - info("BeamNG.drive found in bottle '" + bottle.path().filename().string() + "' at: " + beamngPath.string()); - GameDir = beamngPath.string(); - BottlePath = bottle.path().string(); - info("GameDir: " + GameDir); - info("BottlePath: " + BottlePath); + ProcessBottle(bottlePath); + if (!GameDir.empty()) { return; } } + } else { + fs::path bottlePath = options.bottle_path; + if (!fs::exists(bottlePath)) { + error("Bottle path does not exist: " + bottlePath.string()); + exit(1); + } + ProcessBottle(bottlePath); + if (!GameDir.empty()) { + return; + } } - error("Failed to find BeamNG.drive installation in any CrossOver bottle. Make sure BeamNG.drive is installed in a CrossOver bottle, or set it with the --bottle argument."); + error("Failed to find BeamNG.drive installation in any CrossOver bottle. Make sure BeamNG.drive is installed in a CrossOver bottle, or set it with the --bottle or bottle-path argument."); exit(1); #endif From a27961e60e3968c3fc2ae8be56f13c6816a148e8 Mon Sep 17 00:00:00 2001 From: Fournet Enzo <63660254+enzofrnt@users.noreply.github.com> Date: Tue, 26 Nov 2024 13:11:44 +0100 Subject: [PATCH 78/99] Update src/Options.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Options.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 13284e49..e4e10a20 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -82,14 +82,6 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_update = true; #if defined(__APPLE__) } else if (argument == "--bottle" || argument == "--bottle-path") { - // if (i + 1 >= argc) { - // std::string error_message = - // "No bottle specified, resorting to default"; - // error(error_message); - // i++; - // continue; - // } - if (argument == "--bottle") { options.bottle = argv[i + 1]; } else { From 172f353741b64a8c95dfa76fb65ce752665f1ced Mon Sep 17 00:00:00 2001 From: Fournet Enzo <63660254+enzofrnt@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:17:30 +0100 Subject: [PATCH 79/99] Update src/Network/Core.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Network/Core.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 13a22185..8bd3ce8b 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -384,8 +384,6 @@ int Handle(EXCEPTION_POINTERS* ep) { } catch (...) { error("(Core) Unknown exception"); } -#else - CoreMain(); #endif std::this_thread::sleep_for(std::chrono::seconds(1)); } From 8356becb1cde4079adf8cee19189532691a3ee6b Mon Sep 17 00:00:00 2001 From: Fournet Enzo <63660254+enzofrnt@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:18:31 +0100 Subject: [PATCH 80/99] Update src/Network/Core.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Network/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 8bd3ce8b..7f22a9a2 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -376,7 +376,7 @@ int Handle(EXCEPTION_POINTERS* ep) { __try { CoreMain(); } __except (Handle(GetExceptionInformation())) { } -#elif defined(__linux__) || defined(__APPLE__) +#else try { CoreMain(); } catch (const std::exception& e) { From 78608c151bfebf61b74e3fab33fe225174c10239 Mon Sep 17 00:00:00 2001 From: Fournet Enzo <63660254+enzofrnt@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:18:39 +0100 Subject: [PATCH 81/99] Update src/Network/Core.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Network/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp index 7f22a9a2..5608ba19 100644 --- a/src/Network/Core.cpp +++ b/src/Network/Core.cpp @@ -372,7 +372,7 @@ int Handle(EXCEPTION_POINTERS* ep) { [[noreturn]] void CoreNetwork() { while (true) { -#if defined(_WIN32) && !defined(__MINGW32__) +#if defined(_WIN32) __try { CoreMain(); } __except (Handle(GetExceptionInformation())) { } From 4b738e2d2706b27edd1f778d2b65400514d14500 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 08:20:59 +0100 Subject: [PATCH 82/99] french -> english --- src/Security/BeamNG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index ec1f5da8..6f055f59 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -205,7 +205,7 @@ std::map GetDriveMappings(const std::string& bottlePat } bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { - // Convertir le chemin Windows en style Unix + //Convert the Windows path to Unix path std::string driveLetter = Utils::ToLower(libraryPath.substr(0, libraryPath.find(":"))); driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); @@ -216,7 +216,7 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Wed, 27 Nov 2024 08:24:22 +0100 Subject: [PATCH 83/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 6f055f59..4bae9d19 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -223,14 +223,10 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Wed, 27 Nov 2024 08:24:37 +0100 Subject: [PATCH 84/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 4bae9d19..2a720f4c 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -322,7 +322,7 @@ void LegitimacyCheck() { debug("Crossover bottles path: " + crossoverBottlesPath); - if (empty(options.bottle)) { + if (options.bottle.empty()) { for (const auto& bottle : fs::directory_iterator(crossoverBottlesPath)) { if (bottle.is_directory()) { ProcessBottle(bottle.path()); From b5d3c10126ed00b4c9da2ed85da298896b16e11e Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 08:25:31 +0100 Subject: [PATCH 85/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 2a720f4c..9f0a18c0 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -303,7 +303,7 @@ void LegitimacyCheck() { } #elif defined(__APPLE__) - if (empty(options.bottle_path)) { + if (options.bottle_path.empty()) { const char* homeDir = getpwuid(getuid())->pw_dir; std::string crossoverBottlesPath; From 6583af5fe433365324bcaf1ca4ee53e892cb176b Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 08:28:35 +0100 Subject: [PATCH 86/99] Update Options.cpp --- src/Options.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Options.cpp b/src/Options.cpp index e4e10a20..4abcdb26 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -107,6 +107,7 @@ void InitOptions(int argc, const char *argv[], Options &options) { #if defined(__APPLE__) "\t--bottle Name of the Bottle where the game is located in\n" "\t--bottle-path Path to the Bottle where the game is located in\n" + "\tWARNING: The bottle-path and bottle options cannot be used at the same time\n" #endif "\t--game Passes ALL following arguments to the game, see also `--`\n" << std::flush; From 999c64d87afe6d3d8b77ad3a8e0c4a99030f487f Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 08:33:16 +0100 Subject: [PATCH 87/99] Update Options.cpp --- src/Options.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 4abcdb26..a4e9c823 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -81,13 +81,17 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_launch = true; options.no_update = true; #if defined(__APPLE__) - } else if (argument == "--bottle" || argument == "--bottle-path") { - if (argument == "--bottle") { - options.bottle = argv[i + 1]; - } else { - options.bottle_path = argv[i + 1]; - } - i++; + if ((argument == "--bottle" && !options.bottle_path.empty()) || + (argument == "--bottle-path" && !options.bottle.empty())) { + error("--bottle and --bottle-path cannot be used at the same time."); + exit(1); + } + if (argument == "--bottle") { + options.bottle = argv[i + 1]; + } else { + options.bottle_path = argv[i + 1]; + } + i++; #endif } else if (argument == "--" || argument == "--game") { options.game_arguments = &argv[i + 1]; From ec52f2cfda0b9e58bcd99fe19106490f0cf8a53a Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 09:09:36 +0100 Subject: [PATCH 88/99] option + find game filesystem --- src/Options.cpp | 9 +++------ src/Security/BeamNG.cpp | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index a4e9c823..818631cf 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -81,17 +81,14 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_launch = true; options.no_update = true; #if defined(__APPLE__) - if ((argument == "--bottle" && !options.bottle_path.empty()) || + } else if ((argument == "--bottle" && !options.bottle_path.empty()) || (argument == "--bottle-path" && !options.bottle.empty())) { error("--bottle and --bottle-path cannot be used at the same time."); exit(1); - } - if (argument == "--bottle") { + } else if (argument == "--bottle") { options.bottle = argv[i + 1]; - } else { + } else if (argument == "--bottle-path") { options.bottle_path = argv[i + 1]; - } - i++; #endif } else if (argument == "--" || argument == "--game") { options.game_arguments = &argv[i + 1]; diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 9f0a18c0..75e5f7e6 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -214,16 +214,22 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Wed, 27 Nov 2024 09:11:45 +0100 Subject: [PATCH 89/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 75e5f7e6..c8e71385 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -206,8 +206,8 @@ std::map GetDriveMappings(const std::string& bottlePat bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { //Convert the Windows path to Unix path - std::string driveLetter = Utils::ToLower(libraryPath.substr(0, libraryPath.find(":"))); - driveLetter.erase(std::remove(driveLetter.begin(), driveLetter.end(), ':'), driveLetter.end()); + char driveLetterChar = std::tolower(libraryPath[0]); + std::string driveLetter(1, driveLetterChar); if (!driveMappings.contains(driveLetter)) { warn("Drive letter " + driveLetter + " not found in mappings."); From bd18630759b2ba24d85b98a8dbfeb0b14a1c5f98 Mon Sep 17 00:00:00 2001 From: Fournet Enzo <63660254+enzofrnt@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:07:28 +0100 Subject: [PATCH 90/99] Update src/Options.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Options.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 818631cf..29fec8f1 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -81,8 +81,7 @@ void InitOptions(int argc, const char *argv[], Options &options) { options.no_launch = true; options.no_update = true; #if defined(__APPLE__) - } else if ((argument == "--bottle" && !options.bottle_path.empty()) || - (argument == "--bottle-path" && !options.bottle.empty())) { + } else if ((argument == "--bottle" && !options.bottle_path.empty()) || (argument == "--bottle-path" && !options.bottle.empty())) { error("--bottle and --bottle-path cannot be used at the same time."); exit(1); } else if (argument == "--bottle") { From 059eb7c3b2e286f02fec44f35f4a223e993446ea Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 13:13:28 +0100 Subject: [PATCH 91/99] better drive name --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index c8e71385..659aac8f 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -190,7 +190,7 @@ std::map GetDriveMappings(const std::string& bottlePat for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { std::string driveName = Utils::ToLower(entry.path().filename().string()); - driveName.erase(std::remove(driveName.begin(), driveName.end(), ':'), driveName.end()); + driveName = driveName.substr(0, 1); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); if (!std::filesystem::path(macPath).is_absolute()) { macPath = dosDevicesPath + macPath; From 6b6d86c035094932a7542d7a6b839e03705415a3 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 13:21:58 +0100 Subject: [PATCH 92/99] string to char --- src/Security/BeamNG.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 659aac8f..66e05b3c 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -182,20 +182,20 @@ std::string GetBottleName() { return bottlePath.filename().string(); } -std::map GetDriveMappings(const std::string& bottlePath) { - std::map driveMappings; +std::map GetDriveMappings(const std::string& bottlePath) { + std::map driveMappings; std::string dosDevicesPath = bottlePath + "/dosdevices/"; if (std::filesystem::exists(dosDevicesPath)) { for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { std::string driveName = Utils::ToLower(entry.path().filename().string()); - driveName = driveName.substr(0, 1); + char driveLetter = driveName[0]; std::string macPath = std::filesystem::read_symlink(entry.path()).string(); if (!std::filesystem::path(macPath).is_absolute()) { macPath = dosDevicesPath + macPath; } - driveMappings[driveName] = macPath; + driveMappings[driveLetter] = macPath; } } } else { @@ -204,20 +204,18 @@ std::map GetDriveMappings(const std::string& bottlePat return driveMappings; } -bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { +bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { //Convert the Windows path to Unix path - char driveLetterChar = std::tolower(libraryPath[0]); - std::string driveLetter(1, driveLetterChar); + char driveLetter = std::tolower(libraryPath[0]); if (!driveMappings.contains(driveLetter)) { - warn("Drive letter " + driveLetter + " not found in mappings."); + warn(std::string("Drive letter ") + driveLetter + " not found in mappings."); return false; } std::filesystem::path basePath = driveMappings.at(driveLetter); debug("Base path: " + basePath.string()); - std::filesystem::path cleanLibraryPath = std::filesystem::path(libraryPath.substr(2)).make_preferred(); std::string cleanPathStr = cleanLibraryPath.string(); std::replace(cleanPathStr.begin(), cleanPathStr.end(), '\\', '/'); From 84dd5f3fa38bcf37c8eaf3c06dc0a56eed6cf9b1 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 13:22:50 +0100 Subject: [PATCH 93/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 66e05b3c..48e45a93 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -205,7 +205,6 @@ std::map GetDriveMappings(const std::string& bottlePath) { } bool CheckForGame(const std::string& libraryPath, const std::map& driveMappings) { - //Convert the Windows path to Unix path char driveLetter = std::tolower(libraryPath[0]); if (!driveMappings.contains(driveLetter)) { From 3a7dc0665a293ebe3eee84f243b8d81aeef82054 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Wed, 27 Nov 2024 13:23:23 +0100 Subject: [PATCH 94/99] comment done --- src/Security/BeamNG.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 48e45a93..ea930e39 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -228,7 +228,6 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Wed, 27 Nov 2024 13:35:22 +0100 Subject: [PATCH 95/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index ea930e39..248ad58a 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -219,8 +219,13 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Wed, 27 Nov 2024 15:06:09 +0100 Subject: [PATCH 96/99] Update BeamNG.cpp --- src/Security/BeamNG.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 248ad58a..2ccf6989 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -215,10 +215,10 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Sun, 1 Dec 2024 18:18:35 +0100 Subject: [PATCH 97/99] Update src/Security/BeamNG.cpp Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com> --- src/Security/BeamNG.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 2ccf6989..f761d8de 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -217,17 +217,16 @@ bool CheckForGame(const std::string& libraryPath, const std::map Date: Sun, 1 Dec 2024 18:20:46 +0100 Subject: [PATCH 98/99] ToLower only on letter --- src/Security/BeamNG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 2ccf6989..c8d0476b 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -189,8 +189,8 @@ std::map GetDriveMappings(const std::string& bottlePath) { if (std::filesystem::exists(dosDevicesPath)) { for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { - std::string driveName = Utils::ToLower(entry.path().filename().string()); - char driveLetter = driveName[0]; + char driveLetter = entry.path().filename().string()[0]; + driveLetter = Utils::ToLower(driveLetter); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); if (!std::filesystem::path(macPath).is_absolute()) { macPath = dosDevicesPath + macPath; From 43eabf172365d0e305ec90dfc97b00fb1e5cd336 Mon Sep 17 00:00:00 2001 From: Fournet Enzo Date: Sun, 1 Dec 2024 18:59:33 +0100 Subject: [PATCH 99/99] fix --- src/Security/BeamNG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp index 9bbcd222..bf549568 100644 --- a/src/Security/BeamNG.cpp +++ b/src/Security/BeamNG.cpp @@ -190,7 +190,7 @@ std::map GetDriveMappings(const std::string& bottlePath) { for (const auto& entry : std::filesystem::directory_iterator(dosDevicesPath)) { if (entry.is_symlink()) { char driveLetter = entry.path().filename().string()[0]; - driveLetter = Utils::ToLower(driveLetter); + driveLetter = std::tolower(driveLetter); std::string macPath = std::filesystem::read_symlink(entry.path()).string(); if (!std::filesystem::path(macPath).is_absolute()) { macPath = dosDevicesPath + macPath;