From 50e93d7f2f8d68e08f13b28a59e175eb4046e976 Mon Sep 17 00:00:00 2001 From: 0x90 Date: Wed, 25 Dec 2019 23:03:43 +0100 Subject: [PATCH] [Download] Improve client downloads This is a (partial) fix for issue #14 --- src/Components/Modules/Download.cpp | 152 +++++++++++++++++----------- src/Components/Modules/Download.hpp | 6 +- src/Utils/CSV.cpp | 1 - src/Utils/CSV.hpp | 2 +- 4 files changed, 96 insertions(+), 65 deletions(-) diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index efa55913..08e61095 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -120,65 +120,7 @@ namespace Components if (ev == MG_EV_RECV) { size_t bytes = static_cast(*reinterpret_cast(ev_data)); - fDownload->receivedBytes += bytes; - fDownload->download->downBytes += bytes; - fDownload->download->timeStampBytes += bytes; - - double progress = 0; - if (fDownload->download->totalBytes) - { - progress = (100.0 / fDownload->download->totalBytes) * fDownload->download->downBytes; - } - - static unsigned int dlIndex, dlSize, dlProgress; - dlIndex = fDownload->index + 1; - dlSize = fDownload->download->files.size(); - dlProgress = static_cast(progress); - - static bool framePushed = false; - - if (!framePushed) - { - framePushed = true; - Scheduler::Once([]() - { - framePushed = false; - Dvar::Var("ui_dl_progress").set(Utils::String::VA("(%d/%d) %d%%", dlIndex, dlSize, dlProgress)); - }); - } - - int delta = Game::Sys_Milliseconds() - fDownload->download->lastTimeStamp; - if (delta > 300) - { - bool doFormat = fDownload->download->lastTimeStamp != 0; - fDownload->download->lastTimeStamp = Game::Sys_Milliseconds(); - - size_t dataLeft = fDownload->download->totalBytes - fDownload->download->downBytes; - - int timeLeft = 0; - if (fDownload->download->timeStampBytes) - { - double timeLeftD = ((1.0 * dataLeft) / fDownload->download->timeStampBytes) * delta; - timeLeft = static_cast(timeLeftD); - } - - if (doFormat) - { - static size_t dlTsBytes; - static int dlDelta, dlTimeLeft; - dlTimeLeft = timeLeft; - dlDelta = delta; - dlTsBytes = fDownload->download->timeStampBytes; - - Scheduler::Once([]() - { - Dvar::Var("ui_dl_timeLeft").set(Utils::String::FormatTimeSpan(dlTimeLeft)); - Dvar::Var("ui_dl_transRate").set(Utils::String::FormatBandwidth(dlTsBytes, dlDelta)); - }); - } - - fDownload->download->timeStampBytes = 0; - } + Download::DownloadProgress(fDownload, bytes); } if (ev == MG_EV_HTTP_REPLY) @@ -270,8 +212,12 @@ namespace Components Utils::String::Replace(url, " ", "%20"); + // Just a speedtest ;) + //download->totalBytes = 1048576000; + //url = "http://speed.hetzner.de/1GB.bin"; + download->valid = true; - ZeroMemory(&download->mgr, sizeof download->mgr); + /*ZeroMemory(&download->mgr, sizeof download->mgr); mg_mgr_init(&download->mgr, &fDownload); mg_connect_http(&download->mgr, Download::DownloadHandler, url.data(), nullptr, nullptr); @@ -280,7 +226,28 @@ namespace Components mg_mgr_poll(&download->mgr, 100); } - mg_mgr_free(&download->mgr); + mg_mgr_free(&download->mgr);*/ + + fDownload.downloading = true; + + Utils::WebIO webIO; + webIO.setProgressCallback([&fDownload, &webIO](size_t bytes, size_t) + { + if(!fDownload.downloading || fDownload.download->terminateThread) + { + webIO.cancelDownload(); + return; + } + + Download::DownloadProgress(&fDownload, bytes - fDownload.receivedBytes); + }); + + bool result = false; + fDownload.buffer = webIO.get(url, &result); + if (!result) fDownload.buffer.clear(); + + fDownload.downloading = false; + download->valid = false; if (fDownload.buffer.size() != file.size || Utils::Cryptography::SHA256::Compute(fDownload.buffer, true) != file.hash) @@ -430,6 +397,69 @@ namespace Components return nullptr; } + void Download::DownloadProgress(FileDownload* fDownload, size_t bytes) + { + fDownload->receivedBytes += bytes; + fDownload->download->downBytes += bytes; + fDownload->download->timeStampBytes += bytes; + + static volatile bool framePushed = false; + + if (!framePushed) + { + double progress = 0; + if (fDownload->download->totalBytes) + { + progress = (100.0 / fDownload->download->totalBytes) * fDownload->download->downBytes; + } + + static unsigned int dlIndex, dlSize, dlProgress; + dlIndex = fDownload->index + 1; + dlSize = fDownload->download->files.size(); + dlProgress = static_cast(progress); + + framePushed = true; + Scheduler::Once([]() + { + framePushed = false; + Dvar::Var("ui_dl_progress").set(Utils::String::VA("(%d/%d) %d%%", dlIndex, dlSize, dlProgress)); + }); + } + + int delta = Game::Sys_Milliseconds() - fDownload->download->lastTimeStamp; + if (delta > 300) + { + bool doFormat = fDownload->download->lastTimeStamp != 0; + fDownload->download->lastTimeStamp = Game::Sys_Milliseconds(); + + auto dataLeft = fDownload->download->totalBytes - fDownload->download->downBytes; + + int timeLeft = 0; + if (fDownload->download->timeStampBytes) + { + double timeLeftD = ((1.0 * dataLeft) / fDownload->download->timeStampBytes) * delta; + timeLeft = static_cast(timeLeftD); + } + + if (doFormat) + { + static size_t dlTsBytes; + static int dlDelta, dlTimeLeft; + dlTimeLeft = timeLeft; + dlDelta = delta; + dlTsBytes = fDownload->download->timeStampBytes; + + Scheduler::Once([]() + { + Dvar::Var("ui_dl_timeLeft").set(Utils::String::FormatTimeSpan(dlTimeLeft)); + Dvar::Var("ui_dl_transRate").set(Utils::String::FormatBandwidth(dlTsBytes, dlDelta)); + }); + } + + fDownload->download->timeStampBytes = 0; + } + } + bool Download::VerifyPassword(mg_connection *nc, http_message* message) { std::string g_password = Dvar::Var("g_password").get(); diff --git a/src/Components/Modules/Download.hpp b/src/Components/Modules/Download.hpp index 88d7da5d..1894c079 100644 --- a/src/Components/Modules/Download.hpp +++ b/src/Components/Modules/Download.hpp @@ -26,7 +26,7 @@ namespace Components bool terminateThread; bool isMap; bool isPrivate; - mg_mgr mgr; + //mg_mgr mgr; Network::Address target; std::string hashedPassword; std::string mod; @@ -64,7 +64,7 @@ namespace Components if (this->valid) { this->valid = false; - mg_mgr_free(&(this->mgr)); + //mg_mgr_free(&(this->mgr)); } } }; @@ -212,6 +212,8 @@ namespace Components static bool Terminate; static bool ServerRunning; + static void DownloadProgress(FileDownload* fDownload, size_t bytes); + static bool VerifyPassword(mg_connection *nc, http_message* message); static void EventHandler(mg_connection *nc, int ev, void *ev_data); diff --git a/src/Utils/CSV.cpp b/src/Utils/CSV.cpp index 3b9332c1..380577cb 100644 --- a/src/Utils/CSV.cpp +++ b/src/Utils/CSV.cpp @@ -4,7 +4,6 @@ namespace Utils { CSV::CSV(const std::string& file, bool isFile, bool allowComments) { - this->valid = false; this->parse(file, isFile, allowComments); } diff --git a/src/Utils/CSV.hpp b/src/Utils/CSV.hpp index e2e68fe9..cb1e5567 100644 --- a/src/Utils/CSV.hpp +++ b/src/Utils/CSV.hpp @@ -18,7 +18,7 @@ namespace Utils bool isValid() { return this->valid; } private: - bool valid; + bool valid = false; std::vector> dataMap; void parse(const std::string& file, bool isFile = true, bool allowComments = true);