mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-08-16 08:16:20 +00:00
Change to execution paths to binary paths (#200)
Previously, it used argv[0] for the execution path, which is fine in most cases, but in my case, it is not. The thing is, I use NixOS, and I have created a Nix module for BeamMP. When running BeamMP-Launcher, it tries to check for updates, and fails because of the SHA hash. There are other ways around this, such as setting the execution directory, but I think this is a far clearer approach --- By creating this pull request, I understand that code that is AI generated or otherwise automatically generated may be rejected without further discussion. I declare that I fully understand all code I pushed into this PR, and wrote all this code myself and own the rights to this code.
This commit is contained in:
commit
5b2eb0a1a0
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
void InitLauncher();
|
void InitLauncher();
|
||||||
beammp_fs_string GetEP(const beammp_fs_char* P = nullptr);
|
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::filesystem::path GetGamePath();
|
||||||
std::string GetVer();
|
std::string GetVer();
|
||||||
std::string GetPatch();
|
std::string GetPatch();
|
||||||
|
@ -236,7 +236,7 @@ namespace Utils {
|
|||||||
for (size_t i = 0; i < sha256_len; i++) {
|
for (size_t i = 0; i < sha256_len; i++) {
|
||||||
char buf[3];
|
char buf[3];
|
||||||
sprintf(buf, "%02x", sha256_value[i]);
|
sprintf(buf, "%02x", sha256_value[i]);
|
||||||
buf[2] = NULL;
|
buf[2] = '\0';
|
||||||
result += buf;
|
result += buf;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -280,7 +280,7 @@ namespace Utils {
|
|||||||
for (size_t i = 0; i < sha256_len; i++) {
|
for (size_t i = 0; i < sha256_len; i++) {
|
||||||
char buf[3];
|
char buf[3];
|
||||||
sprintf(buf, "%02x", sha256_value[i]);
|
sprintf(buf, "%02x", sha256_value[i]);
|
||||||
buf[2] = NULL;
|
buf[2] = '\0';
|
||||||
result += buf;
|
result += buf;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -14,7 +14,10 @@
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#elif defined (__APPLE__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <libproc.h>
|
||||||
|
#endif // __APPLE__
|
||||||
#include "Http.h"
|
#include "Http.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Network/network.hpp"
|
#include "Network/network.hpp"
|
||||||
@ -94,6 +97,34 @@ beammp_fs_string GetEP(const beammp_fs_char* P) {
|
|||||||
}();
|
}();
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs::path 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)
|
#if defined(_WIN32)
|
||||||
void ReLaunch() {
|
void ReLaunch() {
|
||||||
std::wstring Arg;
|
std::wstring Arg;
|
||||||
@ -103,7 +134,7 @@ void ReLaunch() {
|
|||||||
}
|
}
|
||||||
info("Relaunch!");
|
info("Relaunch!");
|
||||||
system("cls");
|
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);
|
ShowWindow(GetConsoleWindow(), 0);
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -114,7 +145,7 @@ void URelaunch() {
|
|||||||
Arg += Utils::ToWString(options.argv[c - 1]);
|
Arg += Utils::ToWString(options.argv[c - 1]);
|
||||||
Arg += L" ";
|
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);
|
ShowWindow(GetConsoleWindow(), 0);
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -128,7 +159,7 @@ void ReLaunch() {
|
|||||||
}
|
}
|
||||||
info("Relaunch!");
|
info("Relaunch!");
|
||||||
system("clear");
|
system("clear");
|
||||||
int ret = execv(options.executable_name.c_str(), const_cast<char**>(options.argv));
|
int ret = execv((GetBP() / GetEN()).c_str(), const_cast<char**>(options.argv));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch");
|
error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -137,7 +168,7 @@ void ReLaunch() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
void URelaunch() {
|
void URelaunch() {
|
||||||
int ret = execv(options.executable_name.c_str(), const_cast<char**>(options.argv));
|
int ret = execv((GetBP() / GetEN()).c_str(), const_cast<char**>(options.argv));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch");
|
error(std::string("execv() failed with: ") + strerror(errno) + ". Failed to relaunch");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -169,9 +200,9 @@ void CheckForUpdates(const std::string& CV) {
|
|||||||
"https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey);
|
"https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey);
|
||||||
|
|
||||||
transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower);
|
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);
|
std::string FileHash = Utils::GetSha256HashReallyFastFile(BP);
|
||||||
|
|
||||||
if (FileHash != LatestHash && IsOutdated(Version(VersionStrToInts(GetVer() + GetPatch())), Version(VersionStrToInts(LatestVersion)))) {
|
if (FileHash != LatestHash && IsOutdated(Version(VersionStrToInts(GetVer() + GetPatch())), Version(VersionStrToInts(LatestVersion)))) {
|
||||||
if (!options.no_update) {
|
if (!options.no_update) {
|
||||||
@ -184,16 +215,16 @@ void CheckForUpdates(const std::string& CV) {
|
|||||||
"https://backend.beammp.com/builds/launcher?download=true"
|
"https://backend.beammp.com/builds/launcher?download=true"
|
||||||
"&pk="
|
"&pk="
|
||||||
+ PublicKey + "&branch=" + Branch,
|
+ PublicKey + "&branch=" + Branch,
|
||||||
beammp_wide("new_") + EP, LatestHash);
|
beammp_wide("new_") + BP, LatestHash);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::remove(Back, ec);
|
fs::remove(Back, ec);
|
||||||
if (ec == std::errc::permission_denied) {
|
if (ec == std::errc::permission_denied) {
|
||||||
error("Failed to remove old backup file: " + ec.message() + ". Using alternative name.");
|
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 {
|
} else {
|
||||||
fs::rename(EP, Back);
|
fs::rename(BP, Back);
|
||||||
}
|
}
|
||||||
fs::rename(beammp_wide("new_") + EP, EP);
|
fs::rename(beammp_wide("new_") + BP, BP);
|
||||||
URelaunch();
|
URelaunch();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -254,8 +285,8 @@ void InitLauncher() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t DirCount(const std::filesystem::path& path) {
|
size_t DirCount(const fs::path& path) {
|
||||||
return (size_t)std::distance(std::filesystem::directory_iterator { path }, std::filesystem::directory_iterator {});
|
return (size_t)std::distance(fs::directory_iterator { path }, fs::directory_iterator {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckMP(const beammp_fs_string& Path) {
|
void CheckMP(const beammp_fs_string& Path) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user