Fix merge

This commit is contained in:
Tixx 2025-06-03 11:33:32 +02:00
parent 06c741edc5
commit 6c740e2562
No known key found for this signature in database
GPG Key ID: EC6E7A2BAABF0B8C
6 changed files with 59 additions and 19 deletions

View File

@ -19,6 +19,8 @@
#define beammp_fs_string std::wstring #define beammp_fs_string std::wstring
#define beammp_fs_char wchar_t #define beammp_fs_char wchar_t
#define beammp_wide(str) L##str #define beammp_wide(str) L##str
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else #else
#define beammp_fs_string std::string #define beammp_fs_string std::string
#define beammp_fs_char char #define beammp_fs_char char
@ -71,6 +73,38 @@ namespace Utils {
return result; return result;
} }
#ifdef _WIN32
inline std::wstring ExpandEnvVars(const std::wstring& input) {
std::wstring result;
std::wregex envPattern(LR"(%([^%]+)%|\$([A-Za-z_][A-Za-z0-9_]*)|\$\{([^}]+)\})");
std::wsregex_iterator begin(input.begin(), input.end(), envPattern);
std::wsregex_iterator end;
size_t lastPos = 0;
for (auto it = begin; it != end; ++it) {
const auto& match = *it;
result.append(input, lastPos, match.position() - lastPos);
std::wstring varName;
if (match[1].matched) varName = match[1].str(); // %VAR%
else if (match[2].matched) varName = match[2].str(); // $VAR
else if (match[3].matched) varName = match[3].str(); // ${VAR}
if (const wchar_t* envValue = _wgetenv(varName.c_str())) {
result.append(envValue);
}
lastPos = match.position() + match.length();
}
result.append(input, lastPos, input.length() - lastPos);
return result;
}
#endif
inline std::map<std::string, std::map<std::string, std::string>> ParseINI(const std::string& contents) { inline std::map<std::string, std::map<std::string, std::string>> ParseINI(const std::string& contents) {
std::map<std::string, std::map<std::string, std::string>> ini; std::map<std::string, std::map<std::string, std::string>> ini;
@ -127,12 +161,20 @@ namespace Utils {
return ini; return ini;
} }
inline std::string ToString(const std::wstring& w) {
return std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>>().to_bytes(w);
}
#ifdef _WIN32 #ifdef _WIN32
inline std::wstring ToWString(const std::string& s) { inline std::wstring ToWString(const std::string& s) {
return std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>>().from_bytes(s); if (s.empty()) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), nullptr, 0);
if (size_needed <= 0) {
return L"";
}
std::wstring result(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), &result[0], size_needed);
return result;
} }
#else #else
inline std::string ToWString(const std::string& s) { inline std::string ToWString(const std::string& s) {

View File

@ -6,7 +6,6 @@
#if defined(_WIN32) #if defined(_WIN32)
#include <shlobj.h> #include <shlobj.h>
#include <windows.h>
#elif defined(__linux__) #elif defined(__linux__)
#include "vdf_parser.hpp" #include "vdf_parser.hpp"
#include <pwd.h> #include <pwd.h>
@ -32,14 +31,14 @@ std::wstring QueryKey(HKEY hKey, int ID);
std::wstring GetGamePath() { std::wstring GetGamePath() {
static std::filesystem::path Path; static std::filesystem::path Path;
if (!Path.empty()) if (!Path.empty())
return Path.string(); return Path.wstring();
if (options.user_path) { if (options.user_path) {
if (std::filesystem::exists(options.user_path)) { if (std::filesystem::exists(options.user_path)) {
Path = options.user_path; Path = options.user_path;
debug("Using custom user folder path: " + Path.string()); debug(L"Using custom user folder path: " + Path.wstring());
} else } else
warn("Invalid or non-existent path (" + std::string(options.user_path) + ") specified using --user-path, skipping"); warn(L"Invalid or non-existent path (" + Utils::ToWString(options.user_path) + L") specified using --user-path, skipping");
} }
if (const auto startupIniPath = std::filesystem::path(GetGameDir()) / "startup.ini"; exists(startupIniPath)) { if (const auto startupIniPath = std::filesystem::path(GetGameDir()) / "startup.ini"; exists(startupIniPath)) {
@ -58,16 +57,16 @@ std::wstring GetGamePath() {
} else } else
debug("Successfully parsed startup.ini"); debug("Successfully parsed startup.ini");
std::string userPath; std::wstring userPath;
if (ini.contains("filesystem") && ini["filesystem"].contains("UserPath")) if (ini.contains("filesystem") && ini["filesystem"].contains("UserPath"))
userPath = ini["filesystem"]["UserPath"]; userPath = Utils::ToWString(ini["filesystem"]["UserPath"]);
if (!userPath.empty()) if (!userPath.empty())
if (userPath = Utils::ExpandEnvVars(userPath); std::filesystem::exists(userPath)) { if (userPath = Utils::ExpandEnvVars(userPath); std::filesystem::exists(userPath)) {
Path = userPath; Path = userPath;
debug("Using custom user folder path from startup.ini: " + Path.string()); debug(L"Using custom user folder path from startup.ini: " + Path.wstring());
} else } else
warn("Found custom user folder path (" + userPath + ") in startup.ini but it doesn't exist, skipping"); warn(L"Found custom user folder path (" + userPath + L") in startup.ini but it doesn't exist, skipping");
} }
if (Path.empty()) { if (Path.empty()) {
@ -129,7 +128,7 @@ void StartGame(std::wstring Dir) {
gameArgs += Utils::ToWString(options.game_arguments[i]); gameArgs += Utils::ToWString(options.game_arguments[i]);
} }
debug("BeamNG executable path: " + Dir); debug(L"BeamNG executable path: " + Dir);
bSuccess = CreateProcessW(nullptr, (wchar_t*)(Dir + gameArgs).c_str(), nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi); bSuccess = CreateProcessW(nullptr, (wchar_t*)(Dir + gameArgs).c_str(), nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi);
if (bSuccess) { if (bSuccess) {

View File

@ -12,6 +12,7 @@
#if defined(_WIN32) #if defined(_WIN32)
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <shellapi.h>
#elif defined(__linux__) #elif defined(__linux__)
#include <cstring> #include <cstring>
#include <errno.h> #include <errno.h>

View File

@ -525,7 +525,7 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
CheckForDir(); CheckForDir();
std::string FName = ModInfoIter->FileName; std::string FName = ModInfoIter->FileName;
do { do {
debug("Loading file '" + FName + "' to '" + PathToSaveTo.string() + "'"); debug(L"Loading file '" + Utils::ToWString(FName) + L"' to '" + PathToSaveTo.wstring() + L"'");
TCPSend("f" + ModInfoIter->FileName, Sock); TCPSend("f" + ModInfoIter->FileName, Sock);
std::string Data = TCPRcv(Sock); std::string Data = TCPRcv(Sock);
@ -562,8 +562,8 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
Terminate = true; Terminate = true;
} }
if (GetSha256HashReallyFast(PathToSaveTo) != ModInfoIter->Hash) { if (Utils::GetSha256HashReallyFast(PathToSaveTo) != ModInfoIter->Hash) {
error("Failed to write or download the entire file '" + PathToSaveTo + "' correctly (hash mismatch)"); error(L"Failed to write or download the entire file '" + PathToSaveTo.wstring() + L"' correctly (hash mismatch)");
Terminate = true; Terminate = true;
} }
} while (fs::file_size(PathToSaveTo) != ModInfoIter->FileSize && !Terminate); } while (fs::file_size(PathToSaveTo) != ModInfoIter->FileSize && !Terminate);

View File

@ -7,7 +7,6 @@
#include <filesystem> #include <filesystem>
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h>
#elif defined(__linux__) #elif defined(__linux__)
#include "vdf_parser.hpp" #include "vdf_parser.hpp"
#include <pwd.h> #include <pwd.h>

View File

@ -12,7 +12,6 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <string> #include <string>
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h>
#elif defined(__linux__) #elif defined(__linux__)
#include <unistd.h> #include <unistd.h>
#endif #endif