Etterna 0.74.4
Loading...
Searching...
No Matches
DownloadManager.h
1#pragma once
2#ifndef SM_DOWNMANAGER
3#define SM_DOWNMANAGER
4
5#include "Etterna/Globals/global.h"
6#include "RageUtil/File/RageFile.h"
7#include "Etterna/Models/HighScore/HighScore.h"
8#include "ScreenManager.h"
9#include "RageUtil/File/RageFileManager.h"
10#include "Etterna/Models/Misc/Difficulty.h"
11
12#include "curl/curl.h"
13#include "rapidjson/document.h"
14
15#include <deque>
16#include <unordered_set>
17#include <unordered_map>
18#include <math.h>
19
20class ScoreGoal;
22class RageTexture;
23
25{
26 public:
28 std::atomic<curl_off_t> total{ 0 };
30 std::atomic<curl_off_t> downloaded{ 0 };
32 float time{ 0 };
33};
34
36{
37 public:
38 RageFile file;
39 std::atomic<size_t> bytes{ 0 };
40 std::atomic<bool> stop{ false };
41};
42
44{
45 public:
47 std::string url,
48 std::string filename = "");
49 ~Download();
50 void Install();
51 void Update(float fDeltaSeconds);
52 void Failed();
53 std::string StartMessage()
54 {
55 auto str = "Downloading: " + m_TempFileName;
56 if (str.length() > 64) {
57 str = str.substr(0, 60) + "...";
58 }
59 return str;
60 };
61 std::string Status()
62 {
63 return m_TempFileName + "\n" + speed + " KB/s\n" + "Downloaded " +
64 std::to_string((progress.downloaded.load() > 0
65 ? progress.downloaded.load()
66 : p_RFWrapper.bytes.load()) /
67 1024) +
68 (progress.total.load() > 0
69 ? "/" + std::to_string(progress.total.load() / 1024) + " (KB)"
70 : "");
71 }
72 CURL* handle{ nullptr };
73 int running{ 1 };
74 ProgressData progress;
75 std::string speed{ "" };
76 curl_off_t downloadedAtLastUpdate{ 0 };
77 curl_off_t lastUpdateDone{ 0 };
78 std::string m_Url{ "" };
79 RageFileWrapper p_RFWrapper;
80 DownloadablePack* p_Pack{ nullptr };
81 std::string m_TempFileName{ "" };
82 // Lua
83 void PushSelf(lua_State* L);
84
85 protected:
86 std::string MakeTempFileName(std::string s);
87};
88
90{
91 public:
92 std::string name{ "" };
93 int64_t size{ 0 };
94 int id{ 0 };
95 float avgDifficulty{ 0 };
96 int plays{ 0 };
97 int songs{ 0 };
98 bool nsfw{ false };
99 std::string url{ "" };
100 std::string mirror{ "" };
101 std::string bannerUrl{ "" };
102 std::string thumbnail{ "" };
103 bool downloading{ false };
104 bool isQueued();
105 RageTexture* GetThumbnailTexture();
106 // Lua
107 void PushSelf(lua_State* L);
108};
109
111{
112 public:
113 DownloadablePackPaginationKey(const std::string& searchString,
114 std::set<std::string>& tagFilters,
115 bool tagsMatchAny,
116 int perPage,
117 const std::string& sortField,
118 bool ascendingSort)
119 : searchString(searchString)
120 , tagFilters(tagFilters)
121 , tagsMatchAny(tagsMatchAny)
122 , perPage(perPage)
123 , sortByField(sortField)
124 , sortIsAsc(ascendingSort)
125 {
126 }
128 : searchString("")
129 , tagFilters({})
130 , tagsMatchAny(true)
131 , perPage(0)
132 , sortByField("")
133 , sortIsAsc(true)
134 {
135 }
136
137 bool operator==(const DownloadablePackPaginationKey& other) const
138 {
139 return (perPage == other.perPage) &&
140 (searchString == other.searchString) &&
141 (tagFilters == other.tagFilters) &&
142 (tagsMatchAny == other.tagsMatchAny) &&
143 (sortByField == other.sortByField) &&
144 (sortIsAsc == other.sortIsAsc);
145 }
146
147 std::string searchString{};
148 std::set<std::string> tagFilters{};
149 int perPage = 0;
150 std::string sortByField{};
151 bool sortIsAsc = true;
152 bool tagsMatchAny = true;
153};
154
156{
157 public:
158 DownloadablePackPagination(const std::string& searchString,
159 std::set<std::string>& tagFilters,
160 bool tagsMatchAny,
161 int perPage,
162 const std::string& sortByField,
163 bool sortIsAsc)
164 : key(searchString,
165 tagFilters,
166 tagsMatchAny,
167 perPage,
168 sortByField,
169 sortIsAsc)
170 {
171 }
173 : key(key)
174 {
175 }
177 : key({}) // ??
178 {
179 }
180
181 bool operator==(const DownloadablePackPagination& other)
182 {
183 // under normal circumstances no two paginations
184 // with the same key and different data
185 // should exist
186 return key == other.key;
187 }
188
190
191 int currentPage = 0;
192 int totalEntries = 0;
193 std::vector<DownloadablePack*> results{};
194
195 // if true, page can't move
196 bool pendingRequest = false;
197
198 // if true, a request was made and got no results
199 bool noResults = false;
200
201 bool initialized = false;
202
203 void initialize(LuaReference& whenDone = EMPTY_REFERENCE) {
204 setPage(0, whenDone);
205 }
206
207 // get the cached packs on the current page
208 std::vector<DownloadablePack*> get() {
209 auto it = results.begin();
210 if (results.size() > currentPageStartIndex()) {
211 // make sure the start iterator is valid
212 it += currentPageStartIndex();
213 }
214
215 std::vector<DownloadablePack*> o{};
216
217 while (it != results.end()) {
218 o.push_back(*it);
219 it++;
220 }
221 return o;
222 }
223
224 // get all the packs that are cached
225 std::vector<DownloadablePack*> getCache() { return results; }
226
227 // move to next page and send packs to lua function
228 // possibly invoking a search request
229 void nextPage(LuaReference& whenDone = EMPTY_REFERENCE)
230 {
231 setPage(getNextPageNbr(), whenDone);
232 }
233 // move to prev page and send packs to lua function
234 // possibly invoking a search request
235 void prevPage(LuaReference& whenDone = EMPTY_REFERENCE)
236 {
237 setPage(getPrevPageNbr(), whenDone);
238 }
239
240 // number of pages, so "1" has only a page "0"
241 int getTotalPages() {
242 return static_cast<int>(ceilf(static_cast<float>(totalEntries) /
243 static_cast<float>(key.perPage)));
244 }
245
246 // Lua
247 void PushSelf(lua_State* L);
248
249 private:
251 static LuaReference EMPTY_REFERENCE;
252
253 std::set<int> finishedPageRequests{};
254
255 // return inclusive starting index of page
256 int currentPageStartIndex() {
257 return key.perPage * currentPage;
258 }
259
260 int getNextPageNbr() {
261 if (key.perPage >= totalEntries) {
262 return 0;
263 }
264 if (currentPage == getTotalPages() - 1) {
265 return 0;
266 } else {
267 return currentPage + 1;
268 }
269 }
270 int getPrevPageNbr() {
271 if (key.perPage >= totalEntries) {
272 return 0;
273 }
274 if (currentPage == 0) {
275 return getTotalPages() - 1;
276 } else {
277 return currentPage - 1;
278 }
279 }
280 // move to n page and send packs to lua function
281 // possibly invoking a search request
282 void setPage(int page, LuaReference& whenDone = EMPTY_REFERENCE);
283
284 bool mustRequestPage(int page) {
285 const auto ind = key.perPage * page;
286 if (results.size() <= ind) {
287 // dont make requests out of range
288 return false;
289 }
290 // if null, need to request it
291 return results.at(ind) == nullptr;
292 }
293};
294
295// required to actually use the key as a key
296// in unordered containers
297template<>
299{
300 std::size_t operator()(const DownloadablePackPaginationKey& k) const {
301 size_t r = 17;
302 r = r * 31 + std::hash<int>()(k.perPage);
303 r = r * 31 + std::hash<std::string>()(k.searchString);
304 size_t s = 0;
305 for (const auto& tag : k.tagFilters) {
306 std::hash<std::string> h;
307 s ^= h(tag) + 0x9e3779b9 + (s << 6) + (s >> 2);
308 }
309 r = r * 31 + s;
310 r = r * 31 + std::hash<std::string>()(k.sortByField);
311 r = r * 31 + std::hash<bool>()(k.sortIsAsc);
312 r = r * 31 + std::hash<bool>()(k.tagsMatchAny);
313 return r;
314 }
315};
316
318{
319 // request body
320 std::string packName{};
321 std::string songName{};
322 std::string chartAuthor{};
323 std::string songArtist{};
324 std::vector<std::string> packTags{};
325 bool packTagsMatchAny = true;
326
327 std::string sortBy{};
328 bool sortIsAscending = true;
329
330 // request params (actual names)
331 int page = 0;
332 int per_page = 0;
333
334 auto DebugString() const -> std::string
335 {
336 std::string o = "(ApiSearchCriteria ";
337 o += fmt::format("page: {}, per_page: {}", page, per_page);
338 if (!packName.empty()) {
339 o += fmt::format(", packName: {}", packName);
340 }
341 if (!songName.empty()) {
342 o += fmt::format(", songName: {}", songName);
343 }
344 if (!chartAuthor.empty()) {
345 o += fmt::format(", chartAuthor: {}", chartAuthor);
346 }
347 if (!songArtist.empty()) {
348 o += fmt::format(", songArtist: {}", songArtist);
349 }
350 if (!packTags.empty()) {
351 o += fmt::format(", tags (matchAny={}): [", packTagsMatchAny);
352 for (auto& s : packTags) {
353 o += fmt::format("'{}'", s);
354 }
355 o += "]";
356 }
357 if (!sortBy.empty()) {
358 o += fmt::format(
359 ", sortBy: {}:{}", sortBy, sortIsAscending ? "asc" : "desc");
360 }
361 return o + ")";
362 }
363};
364
365
367{
368 public:
370 CURL* h,
371 std::function<void(HTTPRequest&)> done = [](HTTPRequest& req) {},
372 curl_httppost* postform = nullptr,
373 std::function<void(HTTPRequest&)> fail = [](HTTPRequest& req) {},
374 bool requiresLogin = false)
375 : handle(h)
376 , form(postform)
377 , Done(done)
378 , Failed(fail)
379 , requiresLogin(requiresLogin){};
380 long response_code{ 0 };
381 CURL* handle{ nullptr };
382 curl_httppost* form{ nullptr };
383 std::string result;
384 std::string headers;
385 std::function<void(HTTPRequest&)> Done;
386 std::function<void(HTTPRequest&)> Failed;
387 bool requiresLogin = false;
388};
389enum class RequestMethod
390{
391 GET = 0,
392 POST = 1,
393 PATCH = 2,
394 DEL = 3,
395};
397{
398 public:
399 float wifeScore{ 0.0f };
400 std::string songName;
401 float rate{ 0.0f };
402 float ssr{ 0.0f };
403 float overall{ 0.0f };
404 std::string chartkey;
405 std::string scorekey;
406 Difficulty difficulty;
407 std::string steps;
408};
410{
411 public:
412 bool hasReplay;
413 bool HasReplayData() override { return hasReplay; }
414};
416{
417 public:
418 std::map<Skillset, float> SSRs;
419 float rate{ 0.0f };
420 float wife{ 0.0f };
421 int wifeversion{ 0 };
422 int maxcombo{ 0 };
423 int miss{ 0 };
424 int bad{ 0 };
425 int good{ 0 };
426 int great{ 0 };
427 int perfect{ 0 };
428 int marvelous{ 0 };
429 int minehits{ 0 };
430 int held{ 0 };
431 int holdmiss{ 0 };
432 std::string songId;
433 int letgo{ 0 };
434 bool valid{ false };
435 bool nocc{ false };
436 std::string username;
437 float playerRating{ 0.0f };
438 std::string modifiers;
439 std::string scoreid;
440 std::string avatar;
441 int userid;
442 DateTime datetime;
443 bool hasReplay{ false };
444 std::vector<std::pair<float, float>> replayData;
445 std::string countryCode;
447 void Push(lua_State* L) { hs.PushSelf(L); }
448 bool HasReplayData() { return hasReplay; }
449};
450
452{
453 // new
454 public:
457
459 // Upkeep
460 void Init();
461 void Update(float fDeltaSeconds);
462 void UpdatePacks(float fDeltaSeconds);
463 void UpdateHTTP(float fDeltaSeconds);
464 void UpdateGameplayState(bool gameplay);
465
467 // Lua external access
468 void PushSelf(lua_State* L);
469
471 // State getters
472 bool LoggedIn();
473 bool ShouldUploadScores();
474 bool InGameplay() { return gameplay; }
475
477 // External Facing API Request Generators
478 void Login(
479 const std::string& username,
480 const std::string& password,
481 std::function<void(bool)> done = [](bool loggedIn) {})
482 {
483 LoginRequest(username, password, done);
484 }
485 void LoginWithToken(
486 const std::string& sessionToken,
487 std::function<void(bool)> done = [](bool loggedIn) {});
488 void Logout();
489 void LogoutIfLoggedIn()
490 {
491 if (LoggedIn())
492 Logout();
493 }
494
495 void GetRankedChartkeys(
496 std::function<void(void)> callback = []() {},
497 const DateTime start = DateTime::GetFromString("1990-01-01 12:00:00"),
498 const DateTime end = DateTime::GetFromString("2100-01-01 12:00:00"))
499 {
500 GetRankedChartkeysRequest(callback, start, end);
501 }
502 void AddFavorite(const std::string& chartKey)
503 {
504 AddFavoriteRequest(chartKey);
505 }
506 void BulkAddFavorites(
507 std::vector<std::string> chartKeys,
508 std::function<void()> = []() {});
509 void RemoveFavorite(const std::string& chartKey)
510 {
511 RemoveFavoriteRequest(chartKey);
512 }
513 void RefreshFavorites(
514 const DateTime start = DateTime::GetFromString("1990-01-01 12:00:00"),
515 const DateTime end = DateTime::GetFromString("2100-01-01 12:00:00"));
516 void AddGoal(ScoreGoal* goal) {
517 AddGoalRequest(goal);
518 }
519 void BulkAddGoals(
520 std::vector<ScoreGoal*> goals,
521 std::function<void()> callback = []() {});
522 void UpdateGoal(ScoreGoal* goal) {
523 UpdateGoalRequest(goal);
524 }
525 void RemoveGoal(ScoreGoal* goal, bool oldGoal = false) {
526 RemoveGoalRequest(goal, oldGoal);
527 }
528 void RefreshGoals(
529 const DateTime start = DateTime::GetFromString("1990-01-01 12:00:00"),
530 const DateTime end = DateTime::GetFromString("2100-01-01 12:00:00"));
531 void AddPlaylist(const std::string& name) {
532 AddPlaylistRequest(name);
533 }
534 void UpdatePlaylist(const std::string& name)
535 {
536 UpdatePlaylistRequest(name);
537 }
538 void RemovePlaylist(const std::string& name)
539 {
540 RemovePlaylistRequest(name);
541 }
542 // the point of this is to maintain the online id of playlists
543 void LoadPlaylists(
544 const DateTime start = DateTime::GetFromString("1990-01-01 12:00:00"),
545 const DateTime end = DateTime::GetFromString("2100-01-01 12:00:00"));
546 void DownloadMissingPlaylists(
547 const DateTime start = DateTime::GetFromString("1990-01-01 12:00:00"),
548 const DateTime end = DateTime::GetFromString("2100-01-01 12:00:00"));
549 void DownloadPlaylist(const std::string& name);
550
551 // Score upload functions
552 void UploadScore(HighScore* hs,
553 std::function<void()> callback,
554 bool load_from_disk);
555 void UploadScoreWithReplayData(HighScore* hs);
556 void UploadScoreWithReplayDataFromDisk(
557 HighScore* hs,
558 std::function<void()> callback = []() {});
559 void UploadBulkScores(
560 std::vector<HighScore*> hsList,
561 std::function<void()> callback = []() {});
562
563 void RefreshPackTags();
564 void SearchForPacks(ApiSearchCriteria searchCriteria,
565 std::function<void(rapidjson::Document&)> packSearchParser)
566 {
567 MultiSearchRequest(searchCriteria, packSearchParser);
568 }
569
570 // Mass score upload functions
571 bool ForceUploadPBsForChart(const std::string& ck, bool startNow = false);
572 bool ForceUploadPBsForPack(const std::string& pack, bool startNow = false);
573 bool ForceUploadAllPBs();
574 bool InitialScoreSync();
575
576 void GetChartLeaderboard(const std::string& chartkey,
577 LuaReference& ref = EMPTY_REFERENCE)
578 {
579 GetChartLeaderboardRequest(chartkey, ref);
580 }
581 void GetReplayData(const std::string& scorekey,
582 int userid,
583 const std::string& username,
584 const std::string& chartkey,
585 LuaReference& callback = EMPTY_REFERENCE)
586 {
587 GetReplayDataRequest(scorekey, userid, username, chartkey, callback);
588 }
589
590 OnlineTopScore GetTopSkillsetScore(unsigned int rank,
591 Skillset ss,
592 bool& result);
593 float GetSkillsetRating(Skillset ss);
594 int GetSkillsetRank(Skillset ss);
595
596 DownloadablePackPagination& GetPackPagination(
597 const std::string& searchString,
598 std::set<std::string> tagFilters,
599 bool tagsMatchAny,
600 int perPage,
601 const std::string& sortBy,
602 bool sortIsAsc);
603 std::shared_ptr<Download> DownloadAndInstallPack(const std::string& url,
604 std::string filename = "");
605 std::shared_ptr<Download> DownloadAndInstallPack(DownloadablePack* pack,
606 bool mirror = false);
607
608 void DownloadCoreBundle(const std::string& bundlename, bool mirror = false);
609 std::vector<DownloadablePack*> GetCoreBundle(const std::string& bundlename);
610
611 bool OpenSitePage(const std::string& path);
612 bool OpenProjectPage(const std::string& path);
613
614 bool ShowPackPage(int packid) {
615 return OpenSitePage(fmt::format("/packs/{}", packid));
616 }
617 bool ShowUserPage(const std::string& username){
618 return OpenSitePage(fmt::format("/users/{}", username));
619 }
620 bool ShowScorePage(const std::string& username, int scoreid)
621 {
622 return OpenSitePage(
623 fmt::format("/users/{}/scores/{}", username, scoreid));
624 }
625 bool ShowBugReportSite();
626 bool ShowEditorSite();
627 bool ShowProjectReleases() {
628 return OpenProjectPage("/releases");
629 }
630 bool ShowProjectSite() {
631 return OpenProjectPage("");
632 }
633
635 // User session
636 // Session cookie content
637 std::string authToken{ "" };
638 // Currently logged in username
639 std::string sessionUser{ "" };
640 // Leaderboard ranks for logged in user by skillset
641 std::map<Skillset, int> sessionRanks{};
642 // Online profile skillset ratings
643 std::map<Skillset, double> sessionRatings{};
644
646 // Score uploads
647 std::deque<HighScore*> ScoreUploadSequentialQueue;
648 unsigned int sequentialScoreUploadTotalWorkload{ 0 };
649
651 // Goal uploads
652 std::deque<ScoreGoal*> GoalUploadSequentialQueue;
653 unsigned int sequentialGoalUploadTotalWorkload{ 0 };
654
656 // Favorite uploads
657 std::deque<std::string> FavoriteUploadSequentialQueue;
658 unsigned int sequentialFavoriteUploadTotalWorkload{ 0 };
659
661 // Pack downloads
662 // Active downloads
663 std::map<std::string, std::shared_ptr<Download>> downloads;
664 // (pack,isMirror)
665 std::deque<std::pair<DownloadablePack*, bool>> DownloadQueue;
666 std::map<std::string, std::shared_ptr<Download>> finishedDownloads;
667 std::map<std::string, std::shared_ptr<Download>> pendingInstallDownloads;
668 std::map<int, DownloadablePack> downloadablePacks;
669 std::unordered_map<std::string, std::vector<std::string>> packTags;
670 std::unordered_map<DownloadablePackPaginationKey,
672 downloadablePackPaginations{};
673 // (tag_name, list of pack ids) -- we use this for bundles
674 std::unordered_map<std::string, std::set<int>> tagPacks;
675
677 // Chart leaderboards
678 std::map<std::string, std::vector<OnlineScore>> chartLeaderboards{};
679 std::map<Skillset, std::vector<OnlineTopScore>> topScores{};
680 std::set<std::string> unrankedCharts{};
681 bool currentrateonly = false;
682 bool topscoresonly = true;
683 bool validonly = true;
684
686 // Misc information
687 // Last version according to server (Or current if non was obtained)
688 std::string lastVersion{ "" };
689 std::string countryCode{ "" };
690
691 private:
693 static LuaReference EMPTY_REFERENCE;
694
695 // Events
696 void OnLogin();
697
698 // Checks for generic response codes where we have consistent behavior
699 // status 401 - log out the user, cancel uploads
700 bool HandleAuthErrorResponse(const std::string& endpoint, HTTPRequest& req);
701 // status 429 - requeue the request, wait a while
702 bool HandleRatelimitResponse(const std::string& endpoint, HTTPRequest& req);
703 bool QueueRequestIfRatelimited(const std::string& endpiont,
704 HTTPRequest& req);
705 void QueueRatelimitedRequest(const std::string& endpoint, HTTPRequest& req);
706 // basically returns HandleAuthErrorResponse || HandleRatelimitResponse
707 // and runs the given lambda for the 401 or the 429. Won't run the 429
708 // if a 401 is given first.
709 bool Handle401And429Response(
710 const std::string& endpoint,
711 HTTPRequest& req,
712 std::function<void()> if401 = []() {},
713 std::function<void()> if429 = []() {});
714
715
716 // Specialized API Requests
717 void LoginRequest(const std::string& username,
718 const std::string& password,
719 std::function<void(bool)> done);
720 void GetRankedChartkeysRequest(std::function<void(void)> callback,
721 const DateTime start,
722 const DateTime end);
723 void AddFavoriteRequest(const std::string& chartKey);
724 void RemoveFavoriteRequest(const std::string& chartKey);
725 void GetFavoritesRequest(
726 std::function<void(std::set<std::string>)> onSuccess,
727 const DateTime start,
728 const DateTime end);
729 void AddGoalRequest(ScoreGoal* goal);
730 void UpdateGoalRequest(ScoreGoal* goal);
731 void RemoveGoalRequest(ScoreGoal* goal, bool oldGoal);
732 void GetGoalsRequest(std::function<void(std::vector<ScoreGoal>)> onSuccess,
733 const DateTime start,
734 const DateTime end);
735 void AddPlaylistRequest(const std::string& name);
736 void UpdatePlaylistRequest(const std::string& name);
737 void RemovePlaylistRequest(const std::string& name);
738 void GetPlaylistsRequest(
739 std::function<void(std::unordered_map<std::string, Playlist>)> onSuccess,
740 const DateTime start,
741 const DateTime end);
742 void GetPlaylistRequest(std::function<void(Playlist)> onSuccess, int id);
743 void GetChartLeaderboardRequest(const std::string& chartkey,
744 LuaReference& ref);
745 void GetReplayDataRequest(const std::string& scorekey,
746 int userid,
747 const std::string& username,
748 const std::string& chartkey,
749 LuaReference& callback);
750
751 void RefreshUserData();
752 void RequestTop25(Skillset ss);
753 void RefreshLastVersion();
754
755 void GetPackTagsRequest();
756 void CachePacksForTag(const std::string& tag);
757
758 void MultiSearchRequest(ApiSearchCriteria searchCriteria,
759 std::function<void(rapidjson::Document&)> whenDoneParser);
760
761 // To send a request to API base URL and ratelimit at that URL
762 HTTPRequest* SendRequest(
763 std::string requestName,
764 std::vector<std::pair<std::string, std::string>> params,
765 std::function<void(HTTPRequest&)> done,
766 bool requireLogin = true,
767 RequestMethod httpMethod = RequestMethod::GET,
768 bool compressed = false,
769 bool async = true,
770 bool withBearer = true);
771 // To send a request to API based URL, ratelimit at different path
772 HTTPRequest* SendRequest(
773 std::string requestName,
774 std::string apiPath,
775 std::vector<std::pair<std::string, std::string>> params,
776 std::function<void(HTTPRequest&)> done,
777 bool requireLogin = true,
778 RequestMethod httpMethod = RequestMethod::GET,
779 bool compressed = false,
780 bool async = true,
781 bool withBearer = true);
782 // Send a request directly to a given URL, ratelimit at other path
783 HTTPRequest* SendRequestToURL(
784 std::string url,
785 std::string apiPath,
786 std::vector<std::pair<std::string, std::string>> params,
787 std::function<void(HTTPRequest&)> done,
788 bool requireLogin,
789 RequestMethod httpMethod,
790 bool compressed,
791 bool async,
792 bool withBearer);
793
794 // Active HTTP requests (async, curlMulti)
795 std::vector<HTTPRequest*> HTTPRequests;
796
797 CURLM* pack_multi_handle = nullptr;
798 CURLM* http_req_handle = nullptr;
799
800 // Currently logging in (Since it's async, to not try twice)
801 bool loggingIn{ false };
802 // Currently in gameplay y/n
803 bool gameplay{ false };
804 bool initialized{ false };
805
806 float timeSinceLastDownload = 0.F;
807
808 std::unordered_map<std::string, std::chrono::steady_clock::time_point>
809 endpointRatelimitTimestamps{};
810 std::unordered_map<std::string, std::vector<HTTPRequest*>>
811 ratelimitedRequestQueue{};
812 std::unordered_set<std::string> newlyRankedChartkeys{};
813
814
815 // old
816 public:
817
818 void RefreshPackList(const std::string& url);
819};
820
821extern std::shared_ptr<DownloadManager> DLMAN;
822
823#endif
Definition DownloadManager.h:452
void RefreshPackList(const std::string &url)
Definition DownloadManager.cpp:5552
Definition DownloadManager.h:44
Definition DownloadManager.h:111
Definition DownloadManager.h:156
Definition DownloadManager.h:90
Definition DownloadManager.h:367
A self-cleaning Lua reference.
Definition LuaReference.h:10
Definition DownloadManager.h:416
Definition DownloadManager.h:397
Definition DownloadManager.h:25
float time
seconds passed
Definition DownloadManager.h:32
std::atomic< curl_off_t > total
total bytes
Definition DownloadManager.h:28
std::atomic< curl_off_t > downloaded
bytes downloaded
Definition DownloadManager.h:30
Definition DownloadManager.h:36
High-level file access.
Definition RageFile.h:16
Definition RageTexture.h:14
Definition Profile.h:67
Definition DownloadManager.h:318
A standard way of determining the date and the time.
Definition DateTime.h:81
The high score that is earned by a player.
Definition HighScore.h:18
Definition DownloadManager.h:410
Definition Difficulty.h:63