Skip to content

Commit

Permalink
Fix wstring for windows and add crossplatform code for fs strings
Browse files Browse the repository at this point in the history
  • Loading branch information
WiserTixx committed Jan 26, 2025
1 parent 83a08cb commit 7e109a9
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 129 deletions.
4 changes: 3 additions & 1 deletion include/Http.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

#pragma once
#include "Logger.h"
#include "Utils.h"

#include <string>
class HTTP {
public:
static bool Download(const std::string& IP, const std::wstring& Path);
static bool Download(const std::string& IP, const beammp_fs_string& Path);
static std::string Post(const std::string& IP, const std::string& Fields);
static std::string Get(const std::string& IP);
static bool ProgressBar(size_t c, size_t t);
Expand Down
8 changes: 4 additions & 4 deletions include/Security/Init.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

#pragma once
#include <string>
void PreGame(const std::wstring& GamePath);
std::string CheckVer(const std::wstring& path);
void InitGame(const std::wstring& Dir);
std::wstring GetGameDir();
void PreGame(const beammp_fs_string& GamePath);
std::string CheckVer(const beammp_fs_string& path);
void InitGame(const beammp_fs_string& Dir);
beammp_fs_string GetGameDir();
void LegitimacyCheck();
void CheckLocalKey();
8 changes: 5 additions & 3 deletions include/Startup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
*/

#pragma once
#include "Utils.h"

#include <compare>
#include <string>
#include <vector>

void InitLauncher();
std::wstring GetEP(const wchar_t* P = nullptr);
std::wstring GetGamePath();
beammp_fs_string GetEP(const beammp_fs_char* P = nullptr);
beammp_fs_string GetGamePath();
std::string GetVer();
std::string GetPatch();
std::wstring GetEN();
beammp_fs_string GetEN();
void ConfigInit();
82 changes: 17 additions & 65 deletions include/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
#include <string>
#include <vector>

#ifdef _WIN32
#define beammp_fs_string std::wstring
#define beammp_fs_char wchar_t
#define beammp_wide(str) L##str
#else
#define beammp_fs_string std::string
#define beammp_fs_char char
#define beammp_wide(str) str
#endif

namespace Utils {
inline std::vector<std::string> Split(const std::string& String, const std::string& delimiter) {
std::vector<std::string> Val;
Expand All @@ -28,74 +38,16 @@ namespace Utils {
Val.push_back(s);
return Val;
};
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
inline std::wstring ToWString(const std::string& s) {
return std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>>().from_bytes(s);
}
inline std::string GetSha256HashReallyFast(const std::string& filename) {
try {
EVP_MD_CTX* mdctx;
const EVP_MD* md;
uint8_t sha256_value[EVP_MAX_MD_SIZE];
md = EVP_sha256();
if (md == nullptr) {
throw std::runtime_error("EVP_sha256() failed");
}

mdctx = EVP_MD_CTX_new();
if (mdctx == nullptr) {
throw std::runtime_error("EVP_MD_CTX_new() failed");
}
if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestInit_ex2() failed");
}

std::ifstream stream(filename, std::ios::binary);

const size_t FileSize = std::filesystem::file_size(filename);
size_t Read = 0;
std::vector<char> Data;
while (Read < FileSize) {
Data.resize(size_t(std::min<size_t>(FileSize - Read, 4096)));
size_t RealDataSize = Data.size();
stream.read(Data.data(), std::streamsize(Data.size()));
if (stream.eof() || stream.fail()) {
RealDataSize = size_t(stream.gcount());
}
Data.resize(RealDataSize);
if (RealDataSize == 0) {
break;
}
if (RealDataSize > 0 && !EVP_DigestUpdate(mdctx, Data.data(), Data.size())) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestUpdate() failed");
}
Read += RealDataSize;
}
unsigned int sha256_len = 0;
if (!EVP_DigestFinal_ex(mdctx, sha256_value, &sha256_len)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestFinal_ex() failed");
}
EVP_MD_CTX_free(mdctx);

std::string result;
for (size_t i = 0; i < sha256_len; i++) {
char buf[3];
sprintf(buf, "%02x", sha256_value[i]);
buf[2] = 0;
result += buf;
}
return result;
} catch (const std::exception& e) {
error("Sha256 hashing of '" + filename + "' failed: " + e.what());
return "";
}
#else
inline std::string ToWString(const std::string& s) {
return s;
}
inline std::string GetSha256HashReallyFast(const std::wstring& filename) {
#endif
inline std::string GetSha256HashReallyFast(const beammp_fs_string& filename) {
try {
EVP_MD_CTX* mdctx;
const EVP_MD* md;
Expand Down Expand Up @@ -152,7 +104,7 @@ namespace Utils {
}
return result;
} catch (const std::exception& e) {
error(L"Sha256 hashing of '" + filename + L"' failed: " + ToWString(e.what()));
error(beammp_wide("Sha256 hashing of '") + filename + beammp_wide("' failed: ") + ToWString(e.what()));
return "";
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/GameStart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void StartGame(std::string Dir) {
}
#endif

void InitGame(const std::wstring& Dir) {
void InitGame(const beammp_fs_string& Dir) {
if (!options.no_launch) {
std::thread Game(StartGame, Dir);
Game.detach();
Expand Down
10 changes: 6 additions & 4 deletions src/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ std::string getDate() {
}
void InitLog() {
std::ofstream LFS;
LFS.open(GetEP() + L"Launcher.log");
LFS.open(GetEP() + beammp_wide("Launcher.log"));
if (!LFS.is_open()) {
error("logger file init failed!");
} else
LFS.close();
}
void addToLog(const std::string& Line) {
std::ofstream LFS;
LFS.open(GetEP() + L"Launcher.log", std::ios_base::app);
LFS.open(GetEP() + beammp_wide("Launcher.log"), std::ios_base::app);
LFS << Line.c_str();
LFS.close();
}
void addToLog(const std::wstring& Line) {
std::wofstream LFS;
LFS.open(GetEP() + L"Launcher.log", std::ios_base::app);
LFS.open(GetEP() + beammp_wide("Launcher.log"), std::ios_base::app);
LFS << Line.c_str();
LFS.close();
}
Expand Down Expand Up @@ -91,6 +91,7 @@ void except(const std::string& toPrint) {
}


#ifdef _WIN32
void info(const std::wstring& toPrint) {
std::wstring Print = Utils::ToWString(getDate()) + L"[INFO] " + toPrint + L"\n";
std::wcout << Print;
Expand Down Expand Up @@ -124,4 +125,5 @@ void except(const std::wstring& toPrint) {
std::wstring Print = Utils::ToWString(getDate()) + L"[EXCEP] " + toPrint + L"\n";
std::wcout << Print;
addToLog(Print);
}
}
#endif
4 changes: 2 additions & 2 deletions src/Network/Http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ std::string HTTP::Post(const std::string& IP, const std::string& Fields) {
return Ret;
}

bool HTTP::Download(const std::string& IP, const std::wstring& Path) {
bool HTTP::Download(const std::string& IP, const beammp_fs_string& Path) {
static std::mutex Lock;
std::scoped_lock Guard(Lock);

Expand All @@ -145,7 +145,7 @@ bool HTTP::Download(const std::string& IP, const std::wstring& Path) {
File.close();
info("Download Complete!");
} else {
error(L"Failed to open file directory: " + Path);
error(beammp_wide("Failed to open file directory: ") + Path);
return false;
}

Expand Down
34 changes: 17 additions & 17 deletions src/Network/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,13 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
return;
}
auto FileName = std::filesystem::path(ModInfoIter->FileName).stem().string() + "-" + ModInfoIter->Hash.substr(0, 8) + std::filesystem::path(ModInfoIter->FileName).extension().string();
auto PathToSaveTo = (fs::path(CachingDirectory) / FileName).string();
auto PathToSaveTo = (fs::path(CachingDirectory) / FileName);
if (fs::exists(PathToSaveTo) && Utils::GetSha256HashReallyFast(PathToSaveTo) == ModInfoIter->Hash) {
debug("Mod '" + FileName + "' found in cache");
std::this_thread::sleep_for(std::chrono::milliseconds(50));
try {
if (!fs::exists(GetGamePath() + L"mods/multiplayer")) {
fs::create_directories(GetGamePath() + L"mods/multiplayer");
if (!fs::exists(GetGamePath() + beammp_wide("mods/multiplayer"))) {
fs::create_directories(GetGamePath() + beammp_wide("mods/multiplayer"));
}
auto modname = ModInfoIter->FileName;
#if defined(__linux__)
Expand All @@ -444,14 +444,14 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
WaitForConfirm();
continue;
} else if (auto OldCachedPath = fs::path(CachingDirectory) / std::filesystem::path(ModInfoIter->FileName).filename();
fs::exists(OldCachedPath) && GetSha256HashReallyFast(OldCachedPath.string()) == ModInfoIter->Hash) {
fs::exists(OldCachedPath) && Utils::GetSha256HashReallyFast(OldCachedPath) == ModInfoIter->Hash) {
debug("Mod '" + FileName + "' found in old cache, copying it to the new cache");
std::this_thread::sleep_for(std::chrono::milliseconds(50));
try {
fs::copy_file(OldCachedPath, PathToSaveTo, fs::copy_options::overwrite_existing);

if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
fs::create_directories(GetGamePath() + "mods/multiplayer");
if (!fs::exists(GetGamePath() + beammp_wide("mods/multiplayer"))) {
fs::create_directories(GetGamePath() + beammp_wide("mods/multiplayer"));
}

auto modname = ModInfoIter->FileName;
Expand Down Expand Up @@ -482,7 +482,7 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
CheckForDir();
std::string FName = ModInfoIter->FileName;
do {
debug("Loading file '" + FName + "' to '" + PathToSaveTo + "'");
debug("Loading file '" + FName + "' to '" + PathToSaveTo.string() + "'");
TCPSend("f" + ModInfoIter->FileName, Sock);

std::string Data = TCPRcv(Sock);
Expand All @@ -508,13 +508,13 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
}
// 2. verify size
if (std::filesystem::file_size(PathToSaveTo) != DownloadedFile.size()) {
error("Failed to write the entire file '" + PathToSaveTo + "' correctly (file size mismatch)");
error("Failed to write the entire file '" + PathToSaveTo.string() + "' correctly (file size mismatch)");
Terminate = true;
}
} while (fs::file_size(PathToSaveTo) != ModInfoIter->FileSize && !Terminate);
if (!Terminate) {
if (!fs::exists(GetGamePath() + L"mods/multiplayer")) {
fs::create_directories(GetGamePath() + L"mods/multiplayer");
if (!fs::exists(GetGamePath() + beammp_wide("mods/multiplayer"))) {
fs::create_directories(GetGamePath() + beammp_wide("mods/multiplayer"));
}

// Linux version of the game doesnt support uppercase letters in mod names
Expand Down Expand Up @@ -613,8 +613,8 @@ void SyncResources(SOCKET Sock) {
UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + PathToSaveTo.substr(PathToSaveTo.find_last_of('/')));
std::this_thread::sleep_for(std::chrono::milliseconds(50));
try {
if (!fs::exists(GetGamePath() + L"mods/multiplayer")) {
fs::create_directories(GetGamePath() + L"mods/multiplayer");
if (!fs::exists(GetGamePath() + beammp_wide("mods/multiplayer"))) {
fs::create_directories(GetGamePath() + beammp_wide("mods/multiplayer"));
}
auto modname = PathToSaveTo.substr(PathToSaveTo.find_last_of('/'));
#if defined(__linux__)
Expand All @@ -623,8 +623,8 @@ void SyncResources(SOCKET Sock) {
c = ::tolower(c);
}
#endif
auto name = GetGamePath() + L"mods/multiplayer" + Utils::ToWString(modname);
auto tmp_name = name + L".tmp";
auto name = GetGamePath() + beammp_wide("mods/multiplayer") + Utils::ToWString(modname);
auto tmp_name = name + beammp_wide(".tmp");
fs::copy_file(PathToSaveTo, tmp_name, fs::copy_options::overwrite_existing);
fs::rename(tmp_name, name);
UpdateModUsage(modname);
Expand Down Expand Up @@ -671,8 +671,8 @@ void SyncResources(SOCKET Sock) {
}
} while (fs::file_size(PathToSaveTo) != std::stoull(*FS) && !Terminate);
if (!Terminate) {
if (!fs::exists(GetGamePath() + L"mods/multiplayer")) {
fs::create_directories(GetGamePath() + L"mods/multiplayer");
if (!fs::exists(GetGamePath() + beammp_wide("mods/multiplayer"))) {
fs::create_directories(GetGamePath() + beammp_wide("mods/multiplayer"));
}

// Linux version of the game doesnt support uppercase letters in mod names
Expand All @@ -682,7 +682,7 @@ void SyncResources(SOCKET Sock) {
}
#endif

fs::copy_file(PathToSaveTo, GetGamePath() + L"mods/multiplayer" + Utils::ToWString(FName), fs::copy_options::overwrite_existing);
fs::copy_file(PathToSaveTo, GetGamePath() + beammp_wide("mods/multiplayer") + Utils::ToWString(FName), fs::copy_options::overwrite_existing);
UpdateModUsage(FN->substr(pos));
}
WaitForConfirm();
Expand Down
14 changes: 6 additions & 8 deletions src/Security/BeamNG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <vector>
#endif
#include "Logger.h"
#include "Utils.h"

#include <fstream>
#include <string>
#include <thread>
Expand All @@ -23,7 +25,7 @@
#define MAX_VALUE_NAME 16383

int TraceBack = 0;
std::wstring GameDir;
beammp_fs_string GameDir;

void lowExit(int code) {
TraceBack = 0;
Expand All @@ -33,7 +35,7 @@ void lowExit(int code) {
exit(2);
}

std::wstring GetGameDir() {
beammp_fs_string GetGameDir() {
#if defined(_WIN32)
return GameDir.substr(0, GameDir.find_last_of('\\'));
#elif defined(__linux__)
Expand Down Expand Up @@ -231,13 +233,9 @@ void LegitimacyCheck() {
}
#endif
}
std::string CheckVer(const std::wstring& dir) {
std::string CheckVer(const beammp_fs_string& dir) {
std::string temp;
#if defined(_WIN32)
std::wstring Path = dir + L"\\integrity.json";
#elif defined(__linux__)
std::wstring Path = dir + L"/integrity.json";
#endif
beammp_fs_string Path = dir + beammp_wide("\\integrity.json");
std::ifstream f(Path.c_str(), std::ios::binary);
int Size = int(std::filesystem::file_size(Path));
std::string vec(Size, 0);
Expand Down
Loading

0 comments on commit 7e109a9

Please sign in to comment.