From 7a4b24d6168e0edbb882de3db2a153baa4286395 Mon Sep 17 00:00:00 2001 From: Vali0004 Date: Sat, 26 Jul 2025 10:34:58 -0400 Subject: [PATCH 1/2] Change to canonical paths for executable paths --- include/Startup.h | 1 + src/Startup.cpp | 47 +++++++++++++++++++++++++++++++++++++++-------- src/main.cpp | 1 + 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/include/Startup.h b/include/Startup.h index 55809b8..232036f 100644 --- a/include/Startup.h +++ b/include/Startup.h @@ -13,6 +13,7 @@ void InitLauncher(); beammp_fs_string GetEP(const beammp_fs_char* P = nullptr); +std::filesystem::path GetBP(const beammp_fs_char* P = nullptr); std::filesystem::path GetGamePath(); std::string GetVer(); std::string GetPatch(); diff --git a/src/Startup.cpp b/src/Startup.cpp index 0335877..f6a7cbc 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -14,7 +14,10 @@ #if defined(_WIN32) #elif defined(__linux__) #include -#endif +#elif defined (__APPLE__) +#include +#include +#endif // __APPLE__ #include "Http.h" #include "Logger.h" #include "Network/network.hpp" @@ -94,6 +97,34 @@ beammp_fs_string GetEP(const beammp_fs_char* P) { }(); return Ret; } + +beammp_fs_string GetBP(const beammp_fs_char* P) { + fs::path fspath = {}; +#if defined(_WIN32) + beammp_fs_char path[256]; + GetModuleFileNameW(nullptr, path, sizeof(path)); + fspath = path; +#elif defined(__linux__) + fspath = fs::canonical("/proc/self/exe"); +#elif defined(__APPLE__) + pid_t pid = getpid(); + char path[PROC_PIDPATHINFO_MAXSIZE]; + // While this is fine for a raw executable, + // an application bundle is read-only and these files + // should instead be placed in Application Support. + proc_pidpath(pid, path, sizeof(path)); + fspath = std::string(path); + #else + fspath = beammp_fs_string(P); +#endif + fspath = fs::weakly_canonical(fspath.string() + "/.."); +#if defined(_WIN32) + return fspath.wstring(); +#else + return fspath.string(); +#endif +} + #if defined(_WIN32) void ReLaunch() { std::wstring Arg; @@ -103,7 +134,7 @@ void ReLaunch() { } info("Relaunch!"); system("cls"); - ShellExecuteW(nullptr, L"runas", (GetEP() + GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); + ShellExecuteW(nullptr, L"runas", (GetBP() / GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); ShowWindow(GetConsoleWindow(), 0); std::this_thread::sleep_for(std::chrono::seconds(1)); exit(1); @@ -114,7 +145,7 @@ void URelaunch() { Arg += Utils::ToWString(options.argv[c - 1]); Arg += L" "; } - ShellExecuteW(nullptr, L"open", (GetEP() + GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); + ShellExecuteW(nullptr, L"open", (GetBP() / GetEN()).c_str(), Arg.c_str(), nullptr, SW_SHOWNORMAL); ShowWindow(GetConsoleWindow(), 0); std::this_thread::sleep_for(std::chrono::seconds(1)); exit(1); @@ -128,7 +159,7 @@ void ReLaunch() { } info("Relaunch!"); system("clear"); - int ret = execv(options.executable_name.c_str(), const_cast(options.argv)); + int ret = execv((GetBP() / GetEN()).c_str(), const_cast(options.argv)); if (ret < 0) { error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch"); exit(1); @@ -137,7 +168,7 @@ void ReLaunch() { exit(1); } void URelaunch() { - int ret = execv(options.executable_name.c_str(), const_cast(options.argv)); + int ret = execv((GetBP() / GetEN()).c_str(), const_cast(options.argv)); if (ret < 0) { error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch"); exit(1); @@ -169,7 +200,7 @@ void CheckForUpdates(const std::string& CV) { "https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey); transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower); - beammp_fs_string EP(GetEP() + GetEN()), Back(GetEP() + beammp_wide("BeamMP-Launcher.back")); + beammp_fs_string BP(GetBP() / GetEN()), Back(GetBP() / beammp_wide("BeamMP-Launcher.back")); std::string FileHash = Utils::GetSha256HashReallyFastFile(EP); @@ -254,8 +285,8 @@ void InitLauncher() { } #endif -size_t DirCount(const std::filesystem::path& path) { - return (size_t)std::distance(std::filesystem::directory_iterator { path }, std::filesystem::directory_iterator {}); +size_t DirCount(const fs::path& path) { + return (size_t)std::distance(fs::directory_iterator { path }, fs::directory_iterator {}); } void CheckMP(const beammp_fs_string& Path) { diff --git a/src/main.cpp b/src/main.cpp index b2f9099..0c95cec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,6 +39,7 @@ int main(int argc, const char** argv) try { curl_global_init(CURL_GLOBAL_ALL); GetEP(Utils::ToWString(std::string(argv[0])).c_str()); + info("BP Path: " + GetBP(Utils::ToWString(std::string(argv[0])).c_str())); InitLog(); ConfigInit(); From f27d3c6120ebf2dfe3d25b60ffca6e23552c7195 Mon Sep 17 00:00:00 2001 From: Vali0004 Date: Sat, 2 Aug 2025 00:21:40 -0400 Subject: [PATCH 2/2] Fix bug with BP and not having a trailing slash by default --- include/Utils.h | 4 ++-- src/Startup.cpp | 12 ++++++------ src/main.cpp | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/Utils.h b/include/Utils.h index 3c8381e..c0f4e21 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -236,7 +236,7 @@ namespace Utils { for (size_t i = 0; i < sha256_len; i++) { char buf[3]; sprintf(buf, "%02x", sha256_value[i]); - buf[2] = NULL; + buf[2] = '\0'; result += buf; } return result; @@ -280,7 +280,7 @@ namespace Utils { for (size_t i = 0; i < sha256_len; i++) { char buf[3]; sprintf(buf, "%02x", sha256_value[i]); - buf[2] = NULL; + buf[2] = '\0'; result += buf; } return result; diff --git a/src/Startup.cpp b/src/Startup.cpp index f6a7cbc..5cfcb6d 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -98,7 +98,7 @@ beammp_fs_string GetEP(const beammp_fs_char* P) { return Ret; } -beammp_fs_string GetBP(const beammp_fs_char* P) { +fs::path GetBP(const beammp_fs_char* P) { fs::path fspath = {}; #if defined(_WIN32) beammp_fs_char path[256]; @@ -202,7 +202,7 @@ void CheckForUpdates(const std::string& CV) { transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower); beammp_fs_string BP(GetBP() / GetEN()), Back(GetBP() / beammp_wide("BeamMP-Launcher.back")); - std::string FileHash = Utils::GetSha256HashReallyFastFile(EP); + std::string FileHash = Utils::GetSha256HashReallyFastFile(BP); if (FileHash != LatestHash && IsOutdated(Version(VersionStrToInts(GetVer() + GetPatch())), Version(VersionStrToInts(LatestVersion)))) { if (!options.no_update) { @@ -215,16 +215,16 @@ void CheckForUpdates(const std::string& CV) { "https://backend.beammp.com/builds/launcher?download=true" "&pk=" + PublicKey + "&branch=" + Branch, - beammp_wide("new_") + EP, LatestHash); + beammp_wide("new_") + BP, LatestHash); std::error_code ec; fs::remove(Back, ec); if (ec == std::errc::permission_denied) { error("Failed to remove old backup file: " + ec.message() + ". Using alternative name."); - fs::rename(EP, Back + beammp_wide(".") + Utils::ToWString(FileHash.substr(0, 8))); + fs::rename(BP, Back + beammp_wide(".") + Utils::ToWString(FileHash.substr(0, 8))); } else { - fs::rename(EP, Back); + fs::rename(BP, Back); } - fs::rename(beammp_wide("new_") + EP, EP); + fs::rename(beammp_wide("new_") + BP, BP); URelaunch(); #endif } else { diff --git a/src/main.cpp b/src/main.cpp index 0c95cec..b2f9099 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,6 @@ int main(int argc, const char** argv) try { curl_global_init(CURL_GLOBAL_ALL); GetEP(Utils::ToWString(std::string(argv[0])).c_str()); - info("BP Path: " + GetBP(Utils::ToWString(std::string(argv[0])).c_str())); InitLog(); ConfigInit();