diff --git a/src/LScreens.c b/src/LScreens.c index 1b2e1cc31..ed923c6c4 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -706,12 +706,12 @@ CC_NOINLINE static void MainScreen_GetResume(struct ResumeInfo* info, cc_bool fu info->ip.length && info->port.length; } -CC_NOINLINE static void MainScreen_Error(struct LWebTask* task, const char* action) { +CC_NOINLINE static void MainScreen_Error(struct HttpRequest* req, const char* action) { cc_string str; char strBuffer[STRING_SIZE]; struct MainScreen* s = &MainScreen; String_InitArray(str, strBuffer); - LWebTask_DisplayError(task, action, &str); + Launcher_DisplayHttpError(req, action, &str); LLabel_SetText(&s->lblStatus, &str); s->signingIn = false; } @@ -858,7 +858,7 @@ static void MainScreen_TickCheckUpdates(struct MainScreen* s) { cc_uint32 latest, current; if (!CheckUpdateTask.Base.working) return; - LWebTask_Tick(&CheckUpdateTask.Base); + LWebTask_Tick(&CheckUpdateTask.Base, NULL); if (!CheckUpdateTask.Base.completed) return; if (CheckUpdateTask.Base.success) { @@ -881,15 +881,16 @@ static void MainScreen_LoginPhase2(struct MainScreen* s, const cc_string* user) LLabel_SetConst(&s->lblStatus, "&eRetrieving servers list.."); } +static void MainScreen_SignInError(struct HttpRequest* req) { + MainScreen_Error(req, "signing in"); +} + static void MainScreen_TickGetToken(struct MainScreen* s) { if (!GetTokenTask.Base.working) return; - LWebTask_Tick(&GetTokenTask.Base); - if (!GetTokenTask.Base.completed) return; + LWebTask_Tick(&GetTokenTask.Base, MainScreen_SignInError); - if (!GetTokenTask.Base.success) { - MainScreen_Error(&GetTokenTask.Base, "signing in"); - return; - } + if (!GetTokenTask.Base.completed) return; + if (!GetTokenTask.Base.success) return; if (!GetTokenTask.error && String_CaselessEquals(&GetTokenTask.username, &s->iptUsername.text)) { /* Already logged in, go straight to fetching servers */ @@ -902,7 +903,7 @@ static void MainScreen_TickGetToken(struct MainScreen* s) { static void MainScreen_TickSignIn(struct MainScreen* s) { if (!SignInTask.Base.working) return; - LWebTask_Tick(&SignInTask.Base); + LWebTask_Tick(&SignInTask.Base, MainScreen_SignInError); if (!SignInTask.Base.completed) return; if (SignInTask.needMFA) { MFAScreen_SetActive(); return; } @@ -911,20 +912,19 @@ static void MainScreen_TickSignIn(struct MainScreen* s) { LLabel_SetConst(&s->lblStatus, SignInTask.error); } else if (SignInTask.Base.success) { MainScreen_LoginPhase2(s, &SignInTask.username); - } else { - MainScreen_Error(&SignInTask.Base, "signing in"); } } +static void MainScreen_ServersError(struct HttpRequest* req) { + MainScreen_Error(req, "retrieving servers list"); +} + static void MainScreen_TickFetchServers(struct MainScreen* s) { if (!FetchServersTask.Base.working) return; - LWebTask_Tick(&FetchServersTask.Base); - if (!FetchServersTask.Base.completed) return; + LWebTask_Tick(&FetchServersTask.Base, MainScreen_ServersError); - if (!FetchServersTask.Base.success) { - MainScreen_Error(&FetchServersTask.Base, "retrieving servers list"); - return; - } + if (!FetchServersTask.Base.completed) return; + if (!FetchServersTask.Base.success) return; s->signingIn = false; if (Launcher_AutoHash.length) { @@ -1078,7 +1078,19 @@ static void FetchResourcesScreen_Init(struct LScreen* s_) { s->btnCancel.OnClick = CheckResourcesScreen_Next; } -static void FetchResourcesScreen_Show(struct LScreen* s_) { Fetcher_Run(); } + +static void FetchResourcesScreen_Error(struct HttpRequest* req) { + cc_string str; char buffer[STRING_SIZE]; + String_InitArray(str, buffer); + + Launcher_DisplayHttpError(req, "downloading resources", &str); + LLabel_SetText(&FetchResourcesScreen.lblStatus, &str); +} + +static void FetchResourcesScreen_Show(struct LScreen* s_) { + Fetcher_ErrorCallback = FetchResourcesScreen_Error; + Fetcher_Run(); +} static void FetchResourcesScreen_UpdateStatus(struct FetchResourcesScreen* s, int reqID) { cc_string str; char strBuffer[STRING_SIZE]; @@ -1107,14 +1119,6 @@ static void FetchResourcesScreen_UpdateProgress(struct FetchResourcesScreen* s) LSlider_SetProgress(&s->sdrProgress, progress); } -static void FetchResourcesScreen_Error(struct FetchResourcesScreen* s) { - cc_string str; char buffer[STRING_SIZE]; - String_InitArray(str, buffer); - - Launcher_DisplayHttpError(Fetcher_Result, Fetcher_StatusCode, "downloading resources", &str); - LLabel_SetText(&s->lblStatus, &str); -} - static void FetchResourcesScreen_Tick(struct LScreen* s_) { struct FetchResourcesScreen* s = (struct FetchResourcesScreen*)s_; if (!Fetcher_Working) return; @@ -1123,7 +1127,7 @@ static void FetchResourcesScreen_Tick(struct LScreen* s_) { Fetcher_Update(); if (!Fetcher_Completed) return; - if (Fetcher_Failed) { FetchResourcesScreen_Error(s); return; } + if (Fetcher_Failed) return; Launcher_TryLoadTexturePack(); CheckResourcesScreen_Next(NULL); @@ -1274,11 +1278,11 @@ static void ServersScreen_Tick(struct LScreen* s_) { LScreen_Tick(s_); count = FetchFlagsTask.count; - LWebTask_Tick(&FetchFlagsTask.Base); + LWebTask_Tick(&FetchFlagsTask.Base, NULL); if (count != FetchFlagsTask.count) LBackend_TableFlagAdded(&s->table); if (!FetchServersTask.Base.working) return; - LWebTask_Tick(&FetchServersTask.Base); + LWebTask_Tick(&FetchServersTask.Base, NULL); if (!FetchServersTask.Base.completed) return; if (FetchServersTask.Base.success) { @@ -1644,7 +1648,7 @@ static void UpdatesScreen_Get(cc_bool release, int buildIndex) { static void UpdatesScreen_CheckTick(struct UpdatesScreen* s) { if (!CheckUpdateTask.Base.working) return; - LWebTask_Tick(&CheckUpdateTask.Base); + LWebTask_Tick(&CheckUpdateTask.Base, NULL); if (!CheckUpdateTask.Base.completed) return; UpdatesScreen_FormatBoth(s); @@ -1665,23 +1669,25 @@ static void UpdatesScreen_UpdateProgress(struct UpdatesScreen* s, struct LWebTas LLabel_SetText(&s->lblStatus, &str); } -static void UpdatesScreen_FetchTick(struct UpdatesScreen* s) { +static void FetchUpdatesError(struct HttpRequest* req) { cc_string str; char strBuffer[STRING_SIZE]; + String_InitArray(str, strBuffer); + + Launcher_DisplayHttpError(req, "fetching update", &str); + LLabel_SetText(&UpdatesScreen.lblStatus, &str); +} + +static void UpdatesScreen_FetchTick(struct UpdatesScreen* s) { if (!FetchUpdateTask.Base.working) return; - LWebTask_Tick(&FetchUpdateTask.Base); + LWebTask_Tick(&FetchUpdateTask.Base, FetchUpdatesError); UpdatesScreen_UpdateProgress(s, &FetchUpdateTask.Base); if (!FetchUpdateTask.Base.completed) return; - if (!FetchUpdateTask.Base.success) { - String_InitArray(str, strBuffer); - LWebTask_DisplayError(&FetchUpdateTask.Base, "fetching update", &str); - LLabel_SetText(&s->lblStatus, &str); - } else { - /* FetchUpdateTask handles saving the updated file for us */ - Launcher_ShouldExit = true; - Launcher_ShouldUpdate = true; - } + if (!FetchUpdateTask.Base.success) return; + /* FetchUpdateTask handles saving the updated file for us */ + Launcher_ShouldExit = true; + Launcher_ShouldUpdate = true; } static void UpdatesScreen_Rel_0(void* w) { UpdatesScreen_Get(true, 0); } diff --git a/src/LWeb.c b/src/LWeb.c index 10570cd7f..39d49ec94 100644 --- a/src/LWeb.c +++ b/src/LWeb.c @@ -212,29 +212,23 @@ static void LWebTask_Reset(struct LWebTask* task) { task->completed = false; task->working = true; task->success = false; - task->res = 0; - task->status = 0; } -void LWebTask_Tick(struct LWebTask* task) { +void LWebTask_Tick(struct LWebTask* task, LWebTask_ErrorCallback errorCallback) { struct HttpRequest req; if (task->completed) return; if (!Http_GetResult(task->reqID, &req)) return; - task->res = req.result; - task->status = req.statusCode; - task->working = false; task->completed = true; task->success = req.success; - if (!req.success) return; - task->Handle((cc_uint8*)req.data, req.size); - Mem_Free(req.data); -} - -void LWebTask_DisplayError(struct LWebTask* task, const char* action, cc_string* dst) { - Launcher_DisplayHttpError(task->res, task->status, action, dst); + if (req.success) { + task->Handle((cc_uint8*)req.data, req.size); + Mem_Free(req.data); + } else if (errorCallback) { + errorCallback(&req); + } } void LWebTasks_Init(void) { diff --git a/src/LWeb.h b/src/LWeb.h index 4ed4720af..54aa1659c 100644 --- a/src/LWeb.h +++ b/src/LWeb.h @@ -6,6 +6,7 @@ Copyright 2014-2022 ClassiCube | Licensed under BSD-3 */ +struct HttpRequest; struct JsonContext; typedef void (*JsonOnValue)(struct JsonContext* ctx, const cc_string* v); typedef void (*JsonOnNew)(struct JsonContext* ctx); @@ -53,15 +54,14 @@ struct LWebTask { cc_bool completed; /* Whether the task has finished executing. */ cc_bool working; /* Whether the task is currently in progress, or is scheduled to be. */ cc_bool success; /* Whether the task completed successfully. */ - cc_result res; /* Error returned (e.g. for DNS failure) */ - int status; /* HTTP return code for the request */ int reqID; /* Unique request identifier for this web task. */ /* Called when task successfully downloaded/uploaded data. */ void (*Handle)(cc_uint8* data, cc_uint32 len); }; -void LWebTask_Tick(struct LWebTask* task); -void LWebTask_DisplayError(struct LWebTask* task, const char* action, cc_string* dst); +typedef void (*LWebTask_ErrorCallback)(struct HttpRequest* req); + +void LWebTask_Tick(struct LWebTask* task, LWebTask_ErrorCallback errorCallback); void LWebTasks_Init(void); diff --git a/src/Launcher.c b/src/Launcher.c index b3e8f1d13..cca2358f5 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -53,7 +53,10 @@ void Launcher_SetScreen(struct LScreen* screen) { LBackend_Redraw(); } -void Launcher_DisplayHttpError(cc_result res, int status, const char* action, cc_string* dst) { +void Launcher_DisplayHttpError(struct HttpRequest* req, const char* action, cc_string* dst) { + cc_result res = req->result; + int status = req->statusCode; + if (res) { /* Non HTTP error - this is not good */ Logger_Warn(res, action, Http_DescribeError); @@ -120,9 +123,13 @@ CC_NOINLINE static void StartFromInfo(struct ServerInfo* info) { Launcher_StartGame(&Launcher_Username, &info->mppass, &info->ip, &port, &info->name); } +static void ConnectToServerError(struct HttpRequest* req) { + cc_string logMsg = String_Init(NULL, 0, 0); + Launcher_DisplayHttpError(req, "fetching server info", &logMsg); +} + cc_bool Launcher_ConnectToServer(const cc_string* hash) { struct ServerInfo* info; - cc_string logMsg; int i; if (!hash->length) return false; @@ -139,7 +146,7 @@ cc_bool Launcher_ConnectToServer(const cc_string* hash) { FetchServerTask_Run(hash); while (!FetchServerTask.Base.completed) { - LWebTask_Tick(&FetchServerTask.Base); + LWebTask_Tick(&FetchServerTask.Base, ConnectToServerError); Thread_Sleep(10); } @@ -148,9 +155,6 @@ cc_bool Launcher_ConnectToServer(const cc_string* hash) { return true; } else if (FetchServerTask.Base.success) { Window_ShowDialog("Failed to connect", "No server has that hash"); - } else { - logMsg = String_Init(NULL, 0, 0); - LWebTask_DisplayError(&FetchServerTask.Base, "fetching server info", &logMsg); } return false; } diff --git a/src/Launcher.h b/src/Launcher.h index 5bb7cecf0..8327904b8 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -75,6 +75,6 @@ void Launcher_Run(void); /* Starts the game from the given arguments. */ cc_bool Launcher_StartGame(const cc_string* user, const cc_string* mppass, const cc_string* ip, const cc_string* port, const cc_string* server); /* Prints information about a http error to dst. (for status widget) */ -/* If res is non-zero, also displays a dialog box on-screen. */ -void Launcher_DisplayHttpError(cc_result res, int status, const char* action, cc_string* dst); +/* If req->result is non-zero, also displays a dialog box on-screen. */ +void Launcher_DisplayHttpError(struct HttpRequest* req, const char* action, cc_string* dst); #endif diff --git a/src/Resources.c b/src/Resources.c index eb9da0e23..726b4289f 100644 --- a/src/Resources.c +++ b/src/Resources.c @@ -778,8 +778,8 @@ void Resources_CheckExistence(void) { *-----------------------------------------------------------Fetcher-------------------------------------------------------* *#########################################################################################################################*/ cc_bool Fetcher_Working, Fetcher_Completed, Fetcher_Failed; -int Fetcher_StatusCode, Fetcher_Downloaded; -cc_result Fetcher_Result; +int Fetcher_Downloaded; +FetcherErrorCallback Fetcher_ErrorCallback; const char* Fetcher_RequestName(int reqID) { int i; @@ -845,9 +845,10 @@ CC_NOINLINE static cc_bool Fetcher_Get(int reqID, struct HttpRequest* req) { return true; } - Fetcher_Failed = true; - Fetcher_Result = req->result; - Fetcher_StatusCode = req->statusCode; + /* Only show error for first failed download */ + if (!Fetcher_Failed) Fetcher_ErrorCallback(req); + Fetcher_Failed = true; + Fetcher_Finish(); return false; } diff --git a/src/Resources.h b/src/Resources.h index 962942342..ec0b9e356 100644 --- a/src/Resources.h +++ b/src/Resources.h @@ -4,26 +4,25 @@ /* Implements checking, fetching, and patching the default game assets. Copyright 2014-2022 ClassiCube | Licensed under BSD-3 */ +typedef void (*FetcherErrorCallback)(struct HttpRequest* req); -/* Number of resources that need to be downloaded. */ +/* Number of resources that need to be downloaded */ extern int Resources_Count; -/* Total size of resources that need to be downloaded. */ +/* Total size of resources that need to be downloaded */ extern int Resources_Size; -/* Checks existence of all assets. */ +/* Checks existence of all assets */ void Resources_CheckExistence(void); -/* Whether fetcher is currently downloading resources. */ +/* Whether fetcher is currently downloading resources */ extern cc_bool Fetcher_Working; -/* Whether fetcher has finished. (downloaded all resources, or an error) */ +/* Whether fetcher has finished (downloaded all resources, or an error) */ extern cc_bool Fetcher_Completed; -/* Number of resources that have been downloaded so far. */ +/* Number of resources that have been downloaded so far */ extern int Fetcher_Downloaded; -/* HTTP status code of last failed resource download */ -extern int Fetcher_StatusCode; -/* Error code of last failed resource download. */ -extern cc_result Fetcher_Result; -/* Whether a resource failed to download. */ +/* Whether a resource failed to download */ extern cc_bool Fetcher_Failed; +/* Callback function invoked if a resource fails to download */ +extern FetcherErrorCallback Fetcher_ErrorCallback; /* Finds name of resource associated with given http request. */ const char* Fetcher_RequestName(int reqID);