mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 09:34:35 -05:00
Simplify http error handling in the launcher
This commit is contained in:
parent
6761389db3
commit
2d8fe376f2
7 changed files with 87 additions and 83 deletions
|
@ -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); }
|
||||
|
|
20
src/LWeb.c
20
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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue