Merge pull request #618 from diamante0018/develop
[Download]: Use filesystem library for paths
This commit is contained in:
commit
624b5e4b87
@ -9,19 +9,19 @@ namespace Components
|
|||||||
Download::ClientDownload Download::CLDownload;
|
Download::ClientDownload Download::CLDownload;
|
||||||
|
|
||||||
std::thread Download::ServerThread;
|
std::thread Download::ServerThread;
|
||||||
bool Download::Terminate;
|
volatile bool Download::Terminate;
|
||||||
bool Download::ServerRunning;
|
bool Download::ServerRunning;
|
||||||
|
|
||||||
#pragma region Client
|
#pragma region Client
|
||||||
|
|
||||||
void Download::InitiateMapDownload(const std::string& map, bool needPassword)
|
void Download::InitiateMapDownload(const std::string& map, bool needPassword)
|
||||||
{
|
{
|
||||||
Download::InitiateClientDownload(map, needPassword, true);
|
InitiateClientDownload(map, needPassword, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Download::InitiateClientDownload(const std::string& mod, bool needPassword, bool map)
|
void Download::InitiateClientDownload(const std::string& mod, bool needPassword, bool map)
|
||||||
{
|
{
|
||||||
if (Download::CLDownload.running) return;
|
if (CLDownload.running) return;
|
||||||
|
|
||||||
Scheduler::Once([]
|
Scheduler::Once([]
|
||||||
{
|
{
|
||||||
@ -42,20 +42,20 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Download::CLDownload.hashedPassword = Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(password), "");
|
CLDownload.hashedPassword = Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(password), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
Download::CLDownload.running = true;
|
CLDownload.running = true;
|
||||||
Download::CLDownload.isMap = map;
|
CLDownload.isMap = map;
|
||||||
Download::CLDownload.mod = mod;
|
CLDownload.mod = mod;
|
||||||
Download::CLDownload.terminateThread = false;
|
CLDownload.terminateThread = false;
|
||||||
Download::CLDownload.totalBytes = 0;
|
CLDownload.totalBytes = 0;
|
||||||
Download::CLDownload.lastTimeStamp = 0;
|
CLDownload.lastTimeStamp = 0;
|
||||||
Download::CLDownload.downBytes = 0;
|
CLDownload.downBytes = 0;
|
||||||
Download::CLDownload.timeStampBytes = 0;
|
CLDownload.timeStampBytes = 0;
|
||||||
Download::CLDownload.isPrivate = needPassword;
|
CLDownload.isPrivate = needPassword;
|
||||||
Download::CLDownload.target = Party::Target();
|
CLDownload.target = Party::Target();
|
||||||
Download::CLDownload.thread = std::thread(Download::ModDownloader, &Download::CLDownload);
|
CLDownload.thread = std::thread(ModDownloader, &CLDownload);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Download::ParseModList(ClientDownload* download, const std::string& list)
|
bool Download::ParseModList(ClientDownload* download, const std::string& list)
|
||||||
@ -92,7 +92,7 @@ namespace Components
|
|||||||
const auto name = file.at("name").get<std::string>();
|
const auto name = file.at("name").get<std::string>();
|
||||||
const auto size = file.at("size").get<std::size_t>();
|
const auto size = file.at("size").get<std::size_t>();
|
||||||
|
|
||||||
Download::ClientDownload::File fileEntry;
|
ClientDownload::File fileEntry;
|
||||||
fileEntry.name = name;
|
fileEntry.name = name;
|
||||||
fileEntry.hash = hash;
|
fileEntry.hash = hash;
|
||||||
fileEntry.size = size;
|
fileEntry.size = size;
|
||||||
@ -119,7 +119,7 @@ namespace Components
|
|||||||
|
|
||||||
auto file = download->files[index];
|
auto file = download->files[index];
|
||||||
|
|
||||||
std::string path = download->mod + "/" + file.name;
|
auto path = download->mod + "/" + file.name;
|
||||||
if (download->isMap)
|
if (download->isMap)
|
||||||
{
|
{
|
||||||
path = "usermaps/" + path;
|
path = "usermaps/" + path;
|
||||||
@ -127,8 +127,7 @@ namespace Components
|
|||||||
|
|
||||||
if (Utils::IO::FileExists(path))
|
if (Utils::IO::FileExists(path))
|
||||||
{
|
{
|
||||||
std::string data = Utils::IO::ReadFile(path);
|
auto data = Utils::IO::ReadFile(path);
|
||||||
|
|
||||||
if (data.size() == file.size && Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(data), "") == file.hash)
|
if (data.size() == file.size && Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(data), "") == file.hash)
|
||||||
{
|
{
|
||||||
download->totalBytes += file.size;
|
download->totalBytes += file.size;
|
||||||
@ -185,7 +184,7 @@ namespace Components
|
|||||||
|
|
||||||
Logger::Print("Downloading from url {}\n", url);
|
Logger::Print("Downloading from url {}\n", url);
|
||||||
|
|
||||||
Download::FileDownload fDownload;
|
FileDownload fDownload;
|
||||||
fDownload.file = file;
|
fDownload.file = file;
|
||||||
fDownload.index = index;
|
fDownload.index = index;
|
||||||
fDownload.download = download;
|
fDownload.download = download;
|
||||||
@ -199,7 +198,7 @@ namespace Components
|
|||||||
fDownload.downloading = true;
|
fDownload.downloading = true;
|
||||||
|
|
||||||
Utils::WebIO webIO;
|
Utils::WebIO webIO;
|
||||||
webIO.setProgressCallback([&fDownload, &webIO](size_t bytes, size_t)
|
webIO.setProgressCallback([&fDownload, &webIO](std::size_t bytes, std::size_t)
|
||||||
{
|
{
|
||||||
if(!fDownload.downloading || fDownload.download->terminateThread)
|
if(!fDownload.downloading || fDownload.download->terminateThread)
|
||||||
{
|
{
|
||||||
@ -207,7 +206,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Download::DownloadProgress(&fDownload, bytes - fDownload.receivedBytes);
|
DownloadProgress(&fDownload, bytes - fDownload.receivedBytes);
|
||||||
});
|
});
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -231,13 +230,13 @@ namespace Components
|
|||||||
|
|
||||||
void Download::ModDownloader(ClientDownload* download)
|
void Download::ModDownloader(ClientDownload* download)
|
||||||
{
|
{
|
||||||
if (!download) download = &Download::CLDownload;
|
if (!download) download = &CLDownload;
|
||||||
|
|
||||||
std::string host = "http://" + download->target.getString();
|
auto host = "http://" + download->target.getString();
|
||||||
|
|
||||||
std::string listUrl = host + (download->isMap ? "/map" : "/list") + (download->isPrivate ? ("?password=" + download->hashedPassword) : "");
|
auto listUrl = host + (download->isMap ? "/map" : "/list") + (download->isPrivate ? ("?password=" + download->hashedPassword) : "");
|
||||||
|
|
||||||
std::string list = Utils::WebIO("IW4x", listUrl).setTimeout(5000)->get();
|
auto list = Utils::WebIO("IW4x", listUrl).setTimeout(5000)->get();
|
||||||
if (list.empty())
|
if (list.empty())
|
||||||
{
|
{
|
||||||
if (download->terminateThread) return;
|
if (download->terminateThread) return;
|
||||||
@ -256,7 +255,7 @@ namespace Components
|
|||||||
|
|
||||||
if (download->terminateThread) return;
|
if (download->terminateThread) return;
|
||||||
|
|
||||||
if (!Download::ParseModList(download, list))
|
if (!ParseModList(download, list))
|
||||||
{
|
{
|
||||||
if (download->terminateThread) return;
|
if (download->terminateThread) return;
|
||||||
|
|
||||||
@ -281,7 +280,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (download->terminateThread) return;
|
if (download->terminateThread) return;
|
||||||
|
|
||||||
if (!Download::DownloadFile(download, i))
|
if (!DownloadFile(download, i))
|
||||||
{
|
{
|
||||||
if (download->terminateThread) return;
|
if (download->terminateThread) return;
|
||||||
|
|
||||||
@ -369,7 +368,7 @@ namespace Components
|
|||||||
}, Scheduler::Pipeline::CLIENT);
|
}, Scheduler::Pipeline::CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int delta = Game::Sys_Milliseconds() - fDownload->download->lastTimeStamp;
|
auto delta = Game::Sys_Milliseconds() - fDownload->download->lastTimeStamp;
|
||||||
if (delta > 300)
|
if (delta > 300)
|
||||||
{
|
{
|
||||||
bool doFormat = fDownload->download->lastTimeStamp != 0;
|
bool doFormat = fDownload->download->lastTimeStamp != 0;
|
||||||
@ -386,7 +385,7 @@ namespace Components
|
|||||||
|
|
||||||
if (doFormat)
|
if (doFormat)
|
||||||
{
|
{
|
||||||
static size_t dlTsBytes;
|
static std::size_t dlTsBytes;
|
||||||
static int dlDelta, dlTimeLeft;
|
static int dlDelta, dlTimeLeft;
|
||||||
dlTimeLeft = timeLeft;
|
dlTimeLeft = timeLeft;
|
||||||
dlDelta = delta;
|
dlDelta = delta;
|
||||||
@ -434,7 +433,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// Score and ping are irrelevant
|
// Score and ping are irrelevant
|
||||||
const auto* name = Game::PartyHost_GetMemberName(Game::g_lobbyData, i);
|
const auto* name = Game::PartyHost_GetMemberName(Game::g_lobbyData, i);
|
||||||
if (!name || *name == '\0') continue;
|
if (name == nullptr || *name == '\0') continue;
|
||||||
|
|
||||||
playerInfo["name"] = name;
|
playerInfo["name"] = name;
|
||||||
}
|
}
|
||||||
@ -451,7 +450,7 @@ namespace Components
|
|||||||
static nlohmann::json jsonList;
|
static nlohmann::json jsonList;
|
||||||
static auto handled = false;
|
static auto handled = false;
|
||||||
|
|
||||||
const std::string fs_gameDirVar = (*Game::fs_gameDirVar)->current.string;
|
const std::filesystem::path fs_gameDirVar((*Game::fs_gameDirVar)->current.string);
|
||||||
|
|
||||||
if (!fs_gameDirVar.empty() && !handled)
|
if (!fs_gameDirVar.empty() && !handled)
|
||||||
{
|
{
|
||||||
@ -459,28 +458,30 @@ namespace Components
|
|||||||
|
|
||||||
std::vector<nlohmann::json> fileList;
|
std::vector<nlohmann::json> fileList;
|
||||||
|
|
||||||
const auto path = Dvar::Var("fs_basepath").get<std::string>() + "\\" + fs_gameDirVar;
|
const auto path = Dvar::Var("fs_basepath").get<std::string>() / fs_gameDirVar;
|
||||||
auto list = FileSystem::GetSysFileList(path, "iwd", false);
|
auto list = FileSystem::GetSysFileList(path.generic_string(), "iwd", false);
|
||||||
list.emplace_back("mod.ff");
|
list.emplace_back("mod.ff");
|
||||||
|
|
||||||
for (const auto& file : list)
|
for (const auto& file : list)
|
||||||
{
|
{
|
||||||
std::string filename = path + "\\" + file;
|
auto filename = path / file;
|
||||||
if (file.find("_svr_") == std::string::npos)
|
if (file.find("_svr_") != std::string::npos)
|
||||||
{
|
{
|
||||||
std::unordered_map<std::string, nlohmann::json> jsonFileList;
|
continue;
|
||||||
std::string fileBuffer = Utils::IO::ReadFile(filename);
|
|
||||||
if (fileBuffer.empty())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonFileList["name"] = file;
|
|
||||||
jsonFileList["size"] = fileBuffer.size();
|
|
||||||
jsonFileList["hash"] = Utils::Cryptography::SHA256::Compute(fileBuffer, true);
|
|
||||||
|
|
||||||
fileList.emplace_back(jsonFileList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, nlohmann::json> jsonFileList;
|
||||||
|
auto fileBuffer = Utils::IO::ReadFile(filename.generic_string());
|
||||||
|
if (fileBuffer.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonFileList["name"] = file;
|
||||||
|
jsonFileList["size"] = fileBuffer.size();
|
||||||
|
jsonFileList["hash"] = Utils::Cryptography::SHA256::Compute(fileBuffer, true);
|
||||||
|
|
||||||
|
fileList.emplace_back(jsonFileList);
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonList = fileList;
|
jsonList = fileList;
|
||||||
@ -506,14 +507,15 @@ namespace Components
|
|||||||
|
|
||||||
mapNamePre = mapName;
|
mapNamePre = mapName;
|
||||||
|
|
||||||
const auto path = Dvar::Var("fs_basepath").get<std::string>() + "\\usermaps\\" + mapName;
|
const std::filesystem::path basePath(Dvar::Var("fs_basepath").get<std::string>());
|
||||||
|
const auto path = basePath / "usermaps" / mapName;
|
||||||
|
|
||||||
for (auto i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
|
for (std::size_t i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
|
||||||
{
|
{
|
||||||
const auto filename = path + "\\" + mapName + Maps::UserMapFiles[i];
|
const auto filename = std::format("{}\\{}{}", path.generic_string(), mapName, Maps::UserMapFiles[i]);
|
||||||
|
|
||||||
std::map<std::string, nlohmann::json> file;
|
std::unordered_map<std::string, nlohmann::json> file;
|
||||||
std::string fileBuffer = Utils::IO::ReadFile(filename);
|
auto fileBuffer = Utils::IO::ReadFile(filename);
|
||||||
if (fileBuffer.empty())
|
if (fileBuffer.empty())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -550,7 +552,7 @@ namespace Components
|
|||||||
|
|
||||||
auto mapName = (Party::IsInUserMapLobby() ? Dvar::Var("ui_mapname").get<std::string>() : Maps::GetUserMap()->getName());
|
auto mapName = (Party::IsInUserMapLobby() ? Dvar::Var("ui_mapname").get<std::string>() : Maps::GetUserMap()->getName());
|
||||||
auto isValidFile = false;
|
auto isValidFile = false;
|
||||||
for (auto i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
|
for (std::size_t i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
|
||||||
{
|
{
|
||||||
if (url == (mapName + Maps::UserMapFiles[i]))
|
if (url == (mapName + Maps::UserMapFiles[i]))
|
||||||
{
|
{
|
||||||
@ -684,11 +686,11 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Download::ServerRunning = true;
|
ServerRunning = true;
|
||||||
Download::Terminate = false;
|
Terminate = false;
|
||||||
Download::ServerThread = std::thread([]
|
ServerThread = std::thread([]
|
||||||
{
|
{
|
||||||
while (!Download::Terminate)
|
while (!Terminate)
|
||||||
{
|
{
|
||||||
mg_mgr_poll(&Mgr, 100);
|
mg_mgr_poll(&Mgr, 100);
|
||||||
}
|
}
|
||||||
@ -705,7 +707,7 @@ namespace Components
|
|||||||
|
|
||||||
UIScript::Add("mod_download_cancel", []([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
|
UIScript::Add("mod_download_cancel", []([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
|
||||||
{
|
{
|
||||||
Download::CLDownload.clear();
|
CLDownload.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,7 +720,7 @@ namespace Components
|
|||||||
|
|
||||||
Download::~Download()
|
Download::~Download()
|
||||||
{
|
{
|
||||||
if (Download::ServerRunning)
|
if (ServerRunning)
|
||||||
{
|
{
|
||||||
mg_mgr_free(&Mgr);
|
mg_mgr_free(&Mgr);
|
||||||
}
|
}
|
||||||
@ -726,15 +728,15 @@ namespace Components
|
|||||||
|
|
||||||
void Download::preDestroy()
|
void Download::preDestroy()
|
||||||
{
|
{
|
||||||
Download::Terminate = true;
|
Terminate = true;
|
||||||
if (Download::ServerThread.joinable())
|
if (ServerThread.joinable())
|
||||||
{
|
{
|
||||||
Download::ServerThread.join();
|
ServerThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Dedicated::IsEnabled())
|
if (!Dedicated::IsEnabled())
|
||||||
{
|
{
|
||||||
Download::CLDownload.clear();
|
CLDownload.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ namespace Components
|
|||||||
|
|
||||||
static ClientDownload CLDownload;
|
static ClientDownload CLDownload;
|
||||||
static std::thread ServerThread;
|
static std::thread ServerThread;
|
||||||
static bool Terminate;
|
static volatile bool Terminate;
|
||||||
static bool ServerRunning;
|
static bool ServerRunning;
|
||||||
|
|
||||||
static void DownloadProgress(FileDownload* fDownload, std::size_t bytes);
|
static void DownloadProgress(FileDownload* fDownload, std::size_t bytes);
|
||||||
|
Loading…
Reference in New Issue
Block a user