mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-01 15:36:10 +00:00
Fix download path generation
This commit is contained in:
parent
51d096deac
commit
8025c0884f
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -29,7 +30,7 @@ extern bool Terminate;
|
|||||||
extern uint64_t UDPSock;
|
extern uint64_t UDPSock;
|
||||||
extern uint64_t TCPSock;
|
extern uint64_t TCPSock;
|
||||||
extern std::string Branch;
|
extern std::string Branch;
|
||||||
extern std::string CachingDirectory;
|
extern std::filesystem::path CachingDirectory;
|
||||||
extern bool deleteDuplicateMods;
|
extern bool deleteDuplicateMods;
|
||||||
extern bool TCPTerminate;
|
extern bool TCPTerminate;
|
||||||
extern std::string LastIP;
|
extern std::string LastIP;
|
||||||
|
@ -200,11 +200,11 @@ inline std::wstring ToWString(const std::string& s) {
|
|||||||
throw std::runtime_error("EVP_DigestInit_ex2() failed");
|
throw std::runtime_error("EVP_DigestInit_ex2() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wifstream stream(filename, std::ios::binary);
|
std::ifstream stream(filename, std::ios::binary);
|
||||||
|
|
||||||
const size_t FileSize = std::filesystem::file_size(filename);
|
const size_t FileSize = std::filesystem::file_size(filename);
|
||||||
size_t Read = 0;
|
size_t Read = 0;
|
||||||
std::vector<wchar_t> Data;
|
std::vector<char> Data;
|
||||||
while (Read < FileSize) {
|
while (Read < FileSize) {
|
||||||
Data.resize(size_t(std::min<size_t>(FileSize - Read, 4096)));
|
Data.resize(size_t(std::min<size_t>(FileSize - Read, 4096)));
|
||||||
size_t RealDataSize = Data.size();
|
size_t RealDataSize = Data.size();
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
std::string Branch;
|
std::string Branch;
|
||||||
std::string CachingDirectory = "./Resources";
|
std::filesystem::path CachingDirectory = std::filesystem::path("./Resources");
|
||||||
bool deleteDuplicateMods = false;
|
bool deleteDuplicateMods = false;
|
||||||
|
|
||||||
void ParseConfig(const nlohmann::json& d) {
|
void ParseConfig(const nlohmann::json& d) {
|
||||||
@ -32,8 +32,8 @@ void ParseConfig(const nlohmann::json& d) {
|
|||||||
c = char(tolower(c));
|
c = char(tolower(c));
|
||||||
}
|
}
|
||||||
if (d.contains("CachingDirectory") && d["CachingDirectory"].is_string()) {
|
if (d.contains("CachingDirectory") && d["CachingDirectory"].is_string()) {
|
||||||
CachingDirectory = d["CachingDirectory"].get<std::string>();
|
CachingDirectory = std::filesystem::path(d["CachingDirectory"].get<std::string>());
|
||||||
info("Mod caching directory: " + CachingDirectory);
|
info(L"Mod caching directory: " + CachingDirectory.relative_path().wstring());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.contains("Dev") && d["Dev"].is_boolean()) {
|
if (d.contains("Dev") && d["Dev"].is_boolean()) {
|
||||||
|
@ -47,10 +47,6 @@ std::filesystem::path GetGamePath() {
|
|||||||
std::string contents((std::istreambuf_iterator(startupIni)), std::istreambuf_iterator<char>());
|
std::string contents((std::istreambuf_iterator(startupIni)), std::istreambuf_iterator<char>());
|
||||||
startupIni.close();
|
startupIni.close();
|
||||||
|
|
||||||
if (contents.size() > 3) {
|
|
||||||
contents.erase(0, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ini = Utils::ParseINI(contents);
|
auto ini = Utils::ParseINI(contents);
|
||||||
if (ini.empty()) {
|
if (ini.empty()) {
|
||||||
warn("Failed to parse startup.ini");
|
warn("Failed to parse startup.ini");
|
||||||
|
@ -343,7 +343,7 @@ nlohmann::json modUsage = {};
|
|||||||
|
|
||||||
void UpdateModUsage(const std::string& fileName) {
|
void UpdateModUsage(const std::string& fileName) {
|
||||||
try {
|
try {
|
||||||
fs::path usageFile = fs::path(CachingDirectory) / "mods.json";
|
fs::path usageFile = CachingDirectory / "mods.json";
|
||||||
|
|
||||||
if (!fs::exists(usageFile)) {
|
if (!fs::exists(usageFile)) {
|
||||||
if (std::ofstream file(usageFile); !file.is_open()) {
|
if (std::ofstream file(usageFile); !file.is_open()) {
|
||||||
@ -361,7 +361,7 @@ void UpdateModUsage(const std::string& fileName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (modUsage.empty()) {
|
if (modUsage.empty()) {
|
||||||
auto Size = fs::file_size(fs::path(CachingDirectory) / "mods.json");
|
auto Size = fs::file_size(CachingDirectory / "mods.json");
|
||||||
std::string modsJson(Size, 0);
|
std::string modsJson(Size, 0);
|
||||||
file.read(&modsJson[0], Size);
|
file.read(&modsJson[0], Size);
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto FileName = std::filesystem::path(ModInfoIter->FileName).stem().string() + "-" + ModInfoIter->Hash.substr(0, 8) + std::filesystem::path(ModInfoIter->FileName).extension().string();
|
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);
|
auto PathToSaveTo = (CachingDirectory / FileName);
|
||||||
if (fs::exists(PathToSaveTo) && Utils::GetSha256HashReallyFast(PathToSaveTo) == ModInfoIter->Hash) {
|
if (fs::exists(PathToSaveTo) && Utils::GetSha256HashReallyFast(PathToSaveTo) == ModInfoIter->Hash) {
|
||||||
debug("Mod '" + FileName + "' found in cache");
|
debug("Mod '" + FileName + "' found in cache");
|
||||||
UpdateUl(false, std::to_string(ModNo) + "/" + std::to_string(TotalMods) + ": " + ModInfoIter->FileName);
|
UpdateUl(false, std::to_string(ModNo) + "/" + std::to_string(TotalMods) + ": " + ModInfoIter->FileName);
|
||||||
@ -475,7 +475,7 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
|
|||||||
}
|
}
|
||||||
WaitForConfirm();
|
WaitForConfirm();
|
||||||
continue;
|
continue;
|
||||||
} else if (auto OldCachedPath = fs::path(CachingDirectory) / std::filesystem::path(ModInfoIter->FileName).filename();
|
} else if (auto OldCachedPath = CachingDirectory / std::filesystem::path(ModInfoIter->FileName).filename();
|
||||||
fs::exists(OldCachedPath) && Utils::GetSha256HashReallyFast(OldCachedPath) == ModInfoIter->Hash) {
|
fs::exists(OldCachedPath) && Utils::GetSha256HashReallyFast(OldCachedPath) == ModInfoIter->Hash) {
|
||||||
debug("Mod '" + FileName + "' found in old cache, copying it to the new cache");
|
debug("Mod '" + FileName + "' found in old cache, copying it to the new cache");
|
||||||
UpdateUl(false, std::to_string(ModNo) + "/" + std::to_string(TotalMods) + ": " + ModInfoIter->FileName);
|
UpdateUl(false, std::to_string(ModNo) + "/" + std::to_string(TotalMods) + ": " + ModInfoIter->FileName);
|
||||||
@ -514,7 +514,7 @@ void NewSyncResources(SOCKET Sock, const std::string& Mods, const std::vector<Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ModInfoIter->Protected) {
|
if (ModInfoIter->Protected) {
|
||||||
std::string message = "Mod '" + ModInfoIter->FileName + "' is protected and therefore must be placed in the Resources/Caching folder manually here: " + fs::absolute(CachingDirectory).string();
|
std::string message = "Mod '" + ModInfoIter->FileName + "' is protected and therefore must be placed in the Resources/Caching folder manually here: " + absolute(CachingDirectory).string();
|
||||||
|
|
||||||
error(message);
|
error(message);
|
||||||
UUl(message);
|
UUl(message);
|
||||||
@ -626,7 +626,8 @@ void SyncResources(SOCKET Sock) {
|
|||||||
Ret.clear();
|
Ret.clear();
|
||||||
|
|
||||||
int Amount = 0, Pos = 0;
|
int Amount = 0, Pos = 0;
|
||||||
std::string PathToSaveTo, t;
|
std::filesystem::path PathToSaveTo;
|
||||||
|
std::string t;
|
||||||
for (const std::string& name : FNames) {
|
for (const std::string& name : FNames) {
|
||||||
if (!name.empty()) {
|
if (!name.empty()) {
|
||||||
t += name.substr(name.find_last_of('/') + 1) + ";";
|
t += name.substr(name.find_last_of('/') + 1) + ";";
|
||||||
@ -654,7 +655,7 @@ void SyncResources(SOCKET Sock) {
|
|||||||
for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) {
|
for (auto FN = FNames.begin(), FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN, ++FS) {
|
||||||
auto pos = FN->find_last_of('/');
|
auto pos = FN->find_last_of('/');
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
PathToSaveTo = CachingDirectory + FN->substr(pos);
|
PathToSaveTo = CachingDirectory / std::filesystem::path(*FN).filename();
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -664,13 +665,13 @@ void SyncResources(SOCKET Sock) {
|
|||||||
if (FS->find_first_not_of("0123456789") != std::string::npos)
|
if (FS->find_first_not_of("0123456789") != std::string::npos)
|
||||||
continue;
|
continue;
|
||||||
if (fs::file_size(PathToSaveTo) == FileSize) {
|
if (fs::file_size(PathToSaveTo) == FileSize) {
|
||||||
UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + PathToSaveTo.substr(PathToSaveTo.find_last_of('/')));
|
UpdateUl(false, std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + PathToSaveTo.filename().string());
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
try {
|
try {
|
||||||
if (!fs::exists(GetGamePath() / beammp_wide("mods/multiplayer"))) {
|
if (!fs::exists(GetGamePath() / beammp_wide("mods/multiplayer"))) {
|
||||||
fs::create_directories(GetGamePath() / beammp_wide("mods/multiplayer"));
|
fs::create_directories(GetGamePath() / beammp_wide("mods/multiplayer"));
|
||||||
}
|
}
|
||||||
auto modname = PathToSaveTo.substr(PathToSaveTo.find_last_of('/'));
|
auto modname = PathToSaveTo.filename().string();
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
// Linux version of the game doesnt support uppercase letters in mod names
|
// Linux version of the game doesnt support uppercase letters in mod names
|
||||||
for (char& c : modname) {
|
for (char& c : modname) {
|
||||||
@ -678,7 +679,8 @@ void SyncResources(SOCKET Sock) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
auto name = GetGamePath() / beammp_wide("mods/multiplayer") / Utils::ToWString(modname);
|
auto name = GetGamePath() / beammp_wide("mods/multiplayer") / Utils::ToWString(modname);
|
||||||
auto tmp_name = name / beammp_wide(".tmp");
|
auto tmp_name = name;
|
||||||
|
tmp_name += L".tmp";
|
||||||
fs::copy_file(PathToSaveTo, tmp_name, fs::copy_options::overwrite_existing);
|
fs::copy_file(PathToSaveTo, tmp_name, fs::copy_options::overwrite_existing);
|
||||||
fs::rename(tmp_name, name);
|
fs::rename(tmp_name, name);
|
||||||
UpdateModUsage(modname);
|
UpdateModUsage(modname);
|
||||||
@ -690,12 +692,12 @@ void SyncResources(SOCKET Sock) {
|
|||||||
WaitForConfirm();
|
WaitForConfirm();
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
remove(PathToSaveTo.c_str());
|
fs::remove(PathToSaveTo.wstring());
|
||||||
}
|
}
|
||||||
CheckForDir();
|
CheckForDir();
|
||||||
std::string FName = PathToSaveTo.substr(PathToSaveTo.find_last_of('/'));
|
std::string FName = PathToSaveTo.filename().string();
|
||||||
do {
|
do {
|
||||||
debug("Loading file '" + FName + "' to '" + PathToSaveTo + "'");
|
debug("Loading file '" + FName + "' to '" + PathToSaveTo.string() + "'");
|
||||||
TCPSend("f" + *FN, Sock);
|
TCPSend("f" + *FN, Sock);
|
||||||
|
|
||||||
std::string Data = TCPRcv(Sock);
|
std::string Data = TCPRcv(Sock);
|
||||||
@ -720,7 +722,7 @@ void SyncResources(SOCKET Sock) {
|
|||||||
}
|
}
|
||||||
// 2. verify size
|
// 2. verify size
|
||||||
if (std::filesystem::file_size(PathToSaveTo) != DownloadedFile.size()) {
|
if (std::filesystem::file_size(PathToSaveTo) != DownloadedFile.size()) {
|
||||||
error("Failed to write the entire file '" + PathToSaveTo + "' correctly (file size mismatch)");
|
error(beammp_wide("Failed to write the entire file '") + beammp_fs_string(PathToSaveTo) + beammp_wide("' correctly (file size mismatch)"));
|
||||||
Terminate = true;
|
Terminate = true;
|
||||||
}
|
}
|
||||||
} while (fs::file_size(PathToSaveTo) != std::stoull(*FS) && !Terminate);
|
} while (fs::file_size(PathToSaveTo) != std::stoull(*FS) && !Terminate);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user