From f571e03cfc5a97ef25a61d22b859765bf15c2225 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Fri, 2 Mar 2018 21:10:22 -0300 Subject: [PATCH] Make the pack list request async and filter it --- src/DownloadManager.cpp | 164 ++++++++++++++++++---------------------- src/DownloadManager.h | 12 +-- src/GameLoop.cpp | 2 +- 3 files changed, 80 insertions(+), 98 deletions(-) diff --git a/src/DownloadManager.cpp b/src/DownloadManager.cpp index ef1ae72c0b..798255d545 100644 --- a/src/DownloadManager.cpp +++ b/src/DownloadManager.cpp @@ -262,9 +262,6 @@ DownloadManager::DownloadManager() { lua_settable(L, LUA_GLOBALSINDEX); LUA->Release(L); } - CachePackList(packListURL); - RefreshLastVersion(); - RefreshRegisterPage(); } DownloadManager::~DownloadManager() @@ -364,17 +361,25 @@ Download* DownloadManager::DownloadAndInstallPack(DownloadablePack* pack) dl->p_Pack = pack; return dl; } - -bool DownloadManager::UpdateAndIsFinished(float fDeltaSeconds) +void DownloadManager::init() { - bool packs = UpdatePacksAndIsFinished(fDeltaSeconds); - bool http = UpdateHTTPAndIsFinished(fDeltaSeconds); - return packs && http; + RefreshPackList(packListURL); + RefreshLastVersion(); + RefreshRegisterPage(); + initialized = true; } -bool DownloadManager::UpdateHTTPAndIsFinished(float fDeltaSeconds) +void DownloadManager::Update(float fDeltaSeconds) +{ + if (!initialized) + init(); + UpdatePacks(fDeltaSeconds); + UpdateHTTP(fDeltaSeconds); + return; +} +void DownloadManager::UpdateHTTP(float fDeltaSeconds) { if (!HTTPRunning && HTTPRequests.size() == 0) - return true; + return; timeval timeout; int rc, maxfd = -1; CURLMcode mc; @@ -390,7 +395,7 @@ bool DownloadManager::UpdateHTTPAndIsFinished(float fDeltaSeconds) mc = curl_multi_fdset(mHTTPHandle, &fdread, &fdwrite, &fdexcep, &maxfd); if (mc != CURLM_OK) { error = "curl_multi_fdset() failed, code " + mc; - return false; + return; } if (maxfd == -1) { rc = 0; @@ -433,9 +438,9 @@ bool DownloadManager::UpdateHTTPAndIsFinished(float fDeltaSeconds) } } } - return false; + return; } -bool DownloadManager::UpdatePacksAndIsFinished(float fDeltaSeconds) +void DownloadManager::UpdatePacks(float fDeltaSeconds) { if (pendingInstallDownloads.size() > 0 && !gameplay) { //Install all pending packs @@ -452,7 +457,7 @@ bool DownloadManager::UpdatePacksAndIsFinished(float fDeltaSeconds) SONGMAN->DifferentialReload(); } if (!downloadingPacks) - return true; + return; timeval timeout; int rc, maxfd = -1; CURLMcode mc; @@ -468,7 +473,7 @@ bool DownloadManager::UpdatePacksAndIsFinished(float fDeltaSeconds) mc = curl_multi_fdset(mPackHandle, &fdread, &fdwrite, &fdexcep, &maxfd); if (mc != CURLM_OK) { error = "curl_multi_fdset() failed, code " + mc; - return false; + return; } if (maxfd == -1) { rc = 0; @@ -533,8 +538,7 @@ bool DownloadManager::UpdatePacksAndIsFinished(float fDeltaSeconds) else SONGMAN->DifferentialReload(); } - return false; - + return; } string Download::MakeTempFileName(string s) @@ -721,11 +725,14 @@ OnlineTopScore DownloadManager::GetTopSkillsetScore(unsigned int rank, Skillset return OnlineTopScore(); } -void DownloadManager::SendRequest(string requestName, vector> params, function done , bool requireLogin, bool post, bool async) +void DownloadManager::SendRequest(string requestName, vector> params, function done, bool requireLogin, bool post, bool async) +{ + SendRequestToURL(serverURL.Get() + "/" + requestName, params, done, requireLogin, post, async); +} +void DownloadManager::SendRequestToURL(string url, vector> params, function done, bool requireLogin, bool post, bool async) { if (requireLogin && !LoggedIn()) return; - string url = serverURL.Get()+ "/" + requestName; if (!post && !params.empty()) { url += "?"; for (auto& param : params) @@ -760,6 +767,7 @@ void DownloadManager::SendRequest(string requestName, vector CURLcode res = curl_easy_perform(req->handle); curl_easy_cleanup(req->handle); done(*req); + delete req; } return; } @@ -817,7 +825,7 @@ void DownloadManager::RefreshLastVersion() return; this->lastVersion = json.get("version", GAMESTATE->GetEtternaVersion()).asCString(); }; - SendRequest("client_version", vector>(), done, false, false, false); + SendRequest("client_version", vector>(), done, false, false, true); } void DownloadManager::RefreshRegisterPage() { @@ -828,7 +836,7 @@ void DownloadManager::RefreshRegisterPage() return; this->registerPage = json.get("link", "").asCString(); }; - SendRequest("register_link", vector>(), done, false, false, false); + SendRequest("register_link", vector>(), done, false, false, true); } void DownloadManager::RefreshTop25(Skillset ss) { @@ -981,16 +989,6 @@ bool DownloadManager::UploadScores() return true; } -bool DownloadManager::CachePackList(string url) -{ - bool result; - auto ptr = GetPackList(url, result); - if (!result) - return false; - downloadablePacks = *ptr; - return result; -} - int DownloadManager::GetSkillsetRank(Skillset ss) { if (!LoggedIn()) @@ -1004,68 +1002,50 @@ float DownloadManager::GetSkillsetRating(Skillset ss) return 0.0f; return sessionRatings[ss]; } -vector* DownloadManager::GetPackList(string url, bool &result) +void DownloadManager::RefreshPackList(string url) { - if (url == "") { - result = false; - return nullptr; - } - - CURL *curl = initCURLHandle(); - - SetCURLPostToURL(curl, url); - - string response; - SetCURLResultsString(curl, response); - - CURLcode res = curl_easy_perform(curl); - - curl_easy_cleanup(curl); - if (res != CURLE_OK) { - result = false; - } - Json::Value packs; - RString error; - auto packlist = new vector; - bool parsed = JsonUtil::LoadFromString(packs, response, error); - if (!parsed) { - result = false; - return packlist; - } - string baseUrl = "http://simfiles.stepmania-online.com/"; - - for (int index = 0; index < packs.size(); ++index) { - DownloadablePack tmp; - - if (packs[index].isMember("pack")) - tmp.name = packs[index].get("pack", "").asString(); - else if (packs[index].isMember("packname")) - tmp.name = packs[index].get("packname", "").asString(); - else if (packs[index].isMember("name")) - tmp.name = packs[index].get("name", "").asString(); - else - continue; - - if (packs[index].isMember("url")) - tmp.url = packs[index].get("url", baseUrl + tmp.name + ".zip").asString(); - else - tmp.url = baseUrl + tmp.name + ".zip"; - - if (packs[index].isMember("average")) - tmp.avgDifficulty = static_cast(packs[index].get("average", 0).asDouble()); - else - tmp.avgDifficulty = 0.0; - - if (packs[index].isMember("size")) - tmp.size = packs[index].get("size", 0).asInt(); - else - tmp.size = 0; - - tmp.id = ++lastid; - packlist->push_back(tmp); - } - result = true; - return packlist; + if (url == "") + return; + function done = [](HTTPRequest& req) { + Json::Value packs; + RString error; + auto& packlist = DLMAN->downloadablePacks; + bool parsed = JsonUtil::LoadFromString(packs, req.result, error); + if (!parsed) + return; + DLMAN->downloadablePacks.clear(); + for (int index = 0; index < packs.size(); ++index) { + DownloadablePack tmp; + if (packs[index].isMember("pack")) + tmp.name = packs[index].get("pack", "").asString(); + else if (packs[index].isMember("packname")) + tmp.name = packs[index].get("packname", "").asString(); + else if (packs[index].isMember("name")) + tmp.name = packs[index].get("name", "").asString(); + else + continue; + if (packs[index].isMember("download")) + tmp.url = packs[index].get("download", "").asString(); + else if (packs[index].isMember("url")) + tmp.url = packs[index].get("url", "").asString(); + else + continue; + if (tmp.url.empty()) + continue; + if (packs[index].isMember("average")) + tmp.avgDifficulty = static_cast(packs[index].get("average", 0).asDouble()); + else + tmp.avgDifficulty = 0.0; + if (packs[index].isMember("size")) + tmp.size = packs[index].get("size", 0).asInt(); + else + tmp.size = 0; + tmp.id = ++(DLMAN->lastid); + packlist.push_back(tmp); + } + }; + SendRequestToURL(url, {}, done, false, false, true); + return; } Download::Download(string url) diff --git a/src/DownloadManager.h b/src/DownloadManager.h index a3552a7225..6a866cad47 100644 --- a/src/DownloadManager.h +++ b/src/DownloadManager.h @@ -139,10 +139,10 @@ class DownloadManager int HTTPRunning{ 0 }; bool loggingIn{ false }; // Currently logging in (Since it's async, to not try twice) bool gameplay{ false }; // Currently in gameplay + bool initialized{ false }; string error{ "" }; int lastid{ 0 }; vector downloadablePacks; - bool CachePackList(string url); // Fill downloadablePacks with GetPackList string session{ "" }; // Session cookie content string sessionCookie{ "" }; // Entire session cookie string string sessionUser{ "" }; // Currently logged in username @@ -158,13 +158,14 @@ class DownloadManager void EndSession(); //Sends session destroy request void StartSession(string user, string pass); //Sends login request if not already logging in bool UploadScores(); //Uploads all scores not yet uploaded to current server (Async, 1 request per score) - vector* GetPackList(string url, bool &result); // Blocking (Not asyn/curlMulti) + void RefreshPackList(string url); + void init(); Download* DownloadAndInstallPack(const string &url); Download* DownloadAndInstallPack(DownloadablePack* pack); - bool UpdateAndIsFinished(float fDeltaSeconds); - bool UpdatePacksAndIsFinished(float fDeltaSeconds); - bool UpdateHTTPAndIsFinished(float fDeltaSeconds); + void Update(float fDeltaSeconds); + void UpdatePacks(float fDeltaSeconds); + void UpdateHTTP(float fDeltaSeconds); bool InstallSmzip(const string &sZipFile); void UpdateDLSpeed(); @@ -184,6 +185,7 @@ class DownloadManager inline void SetCURLURL(CURL *curlHandle, string url); void SendRequest(string requestName, vector> params, function done, bool requireLogin = true, bool post = false, bool async = true); + void SendRequestToURL(string url, vector> params, function done, bool requireLogin, bool post, bool async); void RefreshLastVersion(); void RefreshRegisterPage(); void RequestChartLeaderBoard(string chartkey); diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp index e5525efbe2..3f155381d2 100644 --- a/src/GameLoop.cpp +++ b/src/GameLoop.cpp @@ -294,7 +294,7 @@ void GameLoop::RunGameLoop() GAMESTATE->Update(fDeltaTime); SCREENMAN->Update(fDeltaTime); NSMAN->Update(fDeltaTime); - DLMAN->UpdateAndIsFinished(fDeltaTime); + DLMAN->Update(fDeltaTime); /* Important: Process input AFTER updating game logic, or input will be * acting on song beat from last frame */