From 3819e93daddd9c1a0ef76a64fc56368fcf8f3ef7 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 22 Jun 2019 00:28:08 +1000 Subject: [PATCH] Show explanation message for http related errors (like server connecting timeout, SSL error), make showing http error messages more consistent in launcher --- src/ClassiCube.vcxproj.filters | 6 +- src/Http.c | 25 ++++++ src/Http.h | 2 + src/LScreens.c | 24 +++--- src/LWeb.c | 148 ++++++++++++++++++--------------- src/LWeb.h | 15 ++-- src/LWidgets.c | 72 ++++++++-------- src/LWidgets.h | 10 +-- src/Launcher.c | 23 +++-- src/Server.c | 2 +- 10 files changed, 182 insertions(+), 145 deletions(-) diff --git a/src/ClassiCube.vcxproj.filters b/src/ClassiCube.vcxproj.filters index f0c65ad9a..380f8e248 100644 --- a/src/ClassiCube.vcxproj.filters +++ b/src/ClassiCube.vcxproj.filters @@ -401,9 +401,6 @@ Source Files\2D - - Source Files\Platform - Source Files\Utils @@ -548,5 +545,8 @@ Source Files\Network + + Source Files\Game + \ No newline at end of file diff --git a/src/Http.c b/src/Http.c index 77836ca15..f13f2deb3 100644 --- a/src/Http.c +++ b/src/Http.c @@ -15,6 +15,12 @@ #define _UNICODE #endif +#ifdef UNICODE +#define Platform_DecodeString(dst, src, len) String_AppendUtf16(dst, (Codepoint*)(src), (len) * 2) +#else +#define Platform_DecodeString(dst, src, len) String_DecodeCP1252(dst, (uint8_t*)(src), len) +#endif + #include #include #elif defined CC_BUILD_WEB @@ -252,6 +258,7 @@ static void Http_ParseHeader(struct HttpRequest* req, const String* line) { static void Http_SysInit(void) { } static void Http_SysFree(void) { } static void Http_DownloadAsync(struct HttpRequest* req); +bool Http_DescribeError(ReturnCode res, String* dst) { return false; } static void Http_DownloadNextAsync(void) { struct HttpRequest req; @@ -400,6 +407,16 @@ static ReturnCode HttpCache_Lookup(struct HttpCacheEntry* e) { return HttpCache_Insert(i, e); } +bool Http_DescribeError(ReturnCode res, String* dst) { + TCHAR chars[600]; + res = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + GetModuleHandle(TEXT("wininet.dll")), res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), chars, 600, NULL); + if (!res) return false; + + Platform_DecodeString(dst, chars, res); + return true; +} + static void Http_SysInit(void) { /* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */ hInternet = InternetOpenA(GAME_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); @@ -548,6 +565,14 @@ static void Http_SysFree(void) { #elif defined CC_BUILD_CURL static CURL* curl; +bool Http_DescribeError(ReturnCode res, String* dst) { + const char* err = curl_easy_strerror(res); + if (!err) return false; + + String_AppendConst(dst, err); + return true; +} + static void Http_SysInit(void) { CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT); if (res) Logger_Abort2(res, "Failed to init curl"); diff --git a/src/Http.h b/src/Http.h index a1604eb5f..6552a33d9 100644 --- a/src/Http.h +++ b/src/Http.h @@ -62,6 +62,8 @@ void Http_UrlEncodeUtf8(String* dst, const String* src); /* Formats a date for inclusion in HTTP headers. */ /* NOTE: Time is always assumed as being UTC. */ void Http_FormatDate(TimeMS ms, String* str); +/* Outputs more detailed information about errors with http requests. */ +bool Http_DescribeError(ReturnCode res, String* dst); /* Attempts to retrieve a fully completed request. */ /* NOTE: You MUST also check Result/StatusCode, and check Size is > 0. */ diff --git a/src/LScreens.c b/src/LScreens.c index 334e34707..d02cc6359 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -692,17 +692,12 @@ CC_NOINLINE static void MainScreen_GetResume(struct ResumeInfo* info, bool full) CC_NOINLINE static void MainScreen_Error(struct LWebTask* task, const char* action) { String str; char strBuffer[STRING_SIZE]; struct MainScreen* s = &MainScreen_Instance; - String_InitArray(str, strBuffer); - s->SigningIn = false; - if (task->Status) { - String_Format1(&str, "&cclassicube.net returned: %i error", &task->Status); - } else { - String_Format1(&str, "&cError %i when connecting to classicube.net", &task->Res); - } + LWebTask_DisplayError(task, action, &str); LLabel_SetText(&s->LblStatus, &str); LWidget_Redraw(&s->LblStatus); + s->SigningIn = false; } static void MainScreen_Login(void* w, int x, int y) { @@ -886,7 +881,7 @@ static void MainScreen_TickGetToken(struct MainScreen* s) { if (GetTokenTask.Base.Success) { SignInTask_Run(&s->IptUsername.Text, &s->IptPassword.Text); } else { - MainScreen_Error(&GetTokenTask.Base, "sign in"); + MainScreen_Error(&GetTokenTask.Base, "signing in"); } } @@ -910,7 +905,7 @@ static void MainScreen_TickSignIn(struct MainScreen* s) { LLabel_SetText(&s->LblStatus, &fetchMsg); LWidget_Redraw(&s->LblStatus); } else { - MainScreen_Error(&SignInTask.Base, "sign in"); + MainScreen_Error(&SignInTask.Base, "signing in"); } } @@ -1164,7 +1159,7 @@ static void ServersScreen_Connect(void* w, int x, int y) { String* hash = &ServersScreen_Instance.IptHash.Text; if (!hash->length && table->RowsCount) { - hash = <able_Get(table->TopRow)->Hash; + hash = <able_Get(table->TopRow)->hash; } Launcher_ConnectToServer(hash); } @@ -1217,7 +1212,7 @@ static void ServersScreen_ReloadServers(struct ServersScreen* s) { LTable_Sort(&s->Table); for (i = 0; i < FetchServersTask.NumServers; i++) { - FetchFlagsTask_Add(&FetchServersTask.Servers[i].Country); + FetchFlagsTask_Add(&FetchServersTask.Servers[i].country); } } @@ -1521,14 +1516,17 @@ static void UpdatesScreen_UpdateProgress(struct UpdatesScreen* s, struct LWebTas } static void UpdatesScreen_FetchTick(struct UpdatesScreen* s) { - static const String failedMsg = String_FromConst("&cFailed to fetch update"); + String str; char strBuffer[STRING_SIZE]; if (!FetchUpdateTask.Base.Working) return; + LWebTask_Tick(&FetchUpdateTask.Base); UpdatesScreen_UpdateProgress(s, &FetchUpdateTask.Base); if (!FetchUpdateTask.Base.Completed) return; if (!FetchUpdateTask.Base.Success) { - LLabel_SetText(&s->LblStatus, &failedMsg); + String_InitArray(str, strBuffer); + LWebTask_DisplayError(&FetchUpdateTask.Base, "fetching update", &str); + LLabel_SetText(&s->LblStatus, &str); LWidget_Redraw(&s->LblStatus); } else { /* WebTask handles saving of ClassiCube.update for us */ diff --git a/src/LWeb.c b/src/LWeb.c index d54bb964a..c7641356e 100644 --- a/src/LWeb.c +++ b/src/LWeb.c @@ -14,7 +14,7 @@ #define TOKEN_FALSE 3 #define TOKEN_NULL 4 /* Consumes n characters from the JSON stream */ -#define JsonContext_Consume(ctx, n) ctx->Cur += n; ctx->Left -= n; +#define JsonContext_Consume(ctx, n) ctx->cur += n; ctx->left -= n; static const String strTrue = String_FromConst("true"); static const String strFalse = String_FromConst("false"); @@ -30,10 +30,10 @@ static bool Json_IsNumber(char c) { static bool Json_ConsumeConstant(struct JsonContext* ctx, const String* value) { int i; - if (value->length > ctx->Left) return false; + if (value->length > ctx->left) return false; for (i = 0; i < value->length; i++) { - if (ctx->Cur[i] != value->buffer[i]) return false; + if (ctx->cur[i] != value->buffer[i]) return false; } JsonContext_Consume(ctx, value->length); @@ -42,10 +42,10 @@ static bool Json_ConsumeConstant(struct JsonContext* ctx, const String* value) { static int Json_ConsumeToken(struct JsonContext* ctx) { char c; - for (; ctx->Left && Json_IsWhitespace(*ctx->Cur); ) { JsonContext_Consume(ctx, 1); } - if (!ctx->Left) return TOKEN_NONE; + for (; ctx->left && Json_IsWhitespace(*ctx->cur); ) { JsonContext_Consume(ctx, 1); } + if (!ctx->left) return TOKEN_NONE; - c = *ctx->Cur; + c = *ctx->cur; if (c == '{' || c == '}' || c == '[' || c == ']' || c == ',' || c == '"' || c == ':') { JsonContext_Consume(ctx, 1); return c; } @@ -64,8 +64,8 @@ static int Json_ConsumeToken(struct JsonContext* ctx) { static String Json_ConsumeNumber(struct JsonContext* ctx) { int len = 0; - for (; ctx->Left && Json_IsNumber(*ctx->Cur); len++) { JsonContext_Consume(ctx, 1); } - return String_Init(ctx->Cur - len, len, len); + for (; ctx->left && Json_IsNumber(*ctx->cur); len++) { JsonContext_Consume(ctx, 1); } + return String_Init(ctx->cur - len, len, len); } static void Json_ConsumeString(struct JsonContext* ctx, String* str) { @@ -73,23 +73,23 @@ static void Json_ConsumeString(struct JsonContext* ctx, String* str) { char c; str->length = 0; - for (; ctx->Left;) { - c = *ctx->Cur; JsonContext_Consume(ctx, 1); + for (; ctx->left;) { + c = *ctx->cur; JsonContext_Consume(ctx, 1); if (c == '"') return; if (c != '\\') { String_Append(str, c); continue; } /* form of \X */ - if (!ctx->Left) break; - c = *ctx->Cur; JsonContext_Consume(ctx, 1); + if (!ctx->left) break; + c = *ctx->cur; JsonContext_Consume(ctx, 1); if (c == '/' || c == '\\' || c == '"') { String_Append(str, c); continue; } /* form of \uYYYY */ - if (c != 'u' || ctx->Left < 4) break; + if (c != 'u' || ctx->left < 4) break; - if (!PackedCol_Unhex(ctx->Cur[0], &h[0])) break; - if (!PackedCol_Unhex(ctx->Cur[1], &h[1])) break; - if (!PackedCol_Unhex(ctx->Cur[2], &h[2])) break; - if (!PackedCol_Unhex(ctx->Cur[3], &h[3])) break; + if (!PackedCol_Unhex(ctx->cur[0], &h[0])) break; + if (!PackedCol_Unhex(ctx->cur[1], &h[1])) break; + if (!PackedCol_Unhex(ctx->cur[2], &h[2])) break; + if (!PackedCol_Unhex(ctx->cur[3], &h[3])) break; codepoint = (h[0] << 12) | (h[1] << 8) | (h[2] << 4) | h[3]; /* don't want control characters in names/software */ @@ -98,13 +98,13 @@ static void Json_ConsumeString(struct JsonContext* ctx, String* str) { JsonContext_Consume(ctx, 4); } - ctx->Failed = true; str->length = 0; + ctx->failed = true; str->length = 0; } static String Json_ConsumeValue(int token, struct JsonContext* ctx); static void Json_ConsumeObject(struct JsonContext* ctx) { char keyBuffer[STRING_SIZE]; - String value, oldKey = ctx->CurKey; + String value, oldKey = ctx->curKey; int token; ctx->OnNewObject(ctx); @@ -113,19 +113,19 @@ static void Json_ConsumeObject(struct JsonContext* ctx) { if (token == ',') continue; if (token == '}') return; - if (token != '"') { ctx->Failed = true; return; } - String_InitArray(ctx->CurKey, keyBuffer); - Json_ConsumeString(ctx, &ctx->CurKey); + if (token != '"') { ctx->failed = true; return; } + String_InitArray(ctx->curKey, keyBuffer); + Json_ConsumeString(ctx, &ctx->curKey); token = Json_ConsumeToken(ctx); - if (token != ':') { ctx->Failed = true; return; } + if (token != ':') { ctx->failed = true; return; } token = Json_ConsumeToken(ctx); - if (token == TOKEN_NONE) { ctx->Failed = true; return; } + if (token == TOKEN_NONE) { ctx->failed = true; return; } value = Json_ConsumeValue(token, ctx); ctx->OnValue(ctx, &value); - ctx->CurKey = oldKey; + ctx->curKey = oldKey; } } @@ -139,7 +139,7 @@ static void Json_ConsumeArray(struct JsonContext* ctx) { if (token == ',') continue; if (token == ']') return; - if (token == TOKEN_NONE) { ctx->Failed = true; return; } + if (token == TOKEN_NONE) { ctx->failed = true; return; } value = Json_ConsumeValue(token, ctx); ctx->OnValue(ctx, &value); } @@ -162,10 +162,10 @@ static String Json_ConsumeValue(int token, struct JsonContext* ctx) { static void Json_NullOnNew(struct JsonContext* ctx) { } static void Json_NullOnValue(struct JsonContext* ctx, const String* v) { } void Json_Init(struct JsonContext* ctx, String* str) { - ctx->Cur = str->buffer; - ctx->Left = str->length; - ctx->Failed = false; - ctx->CurKey = String_Empty; + ctx->cur = str->buffer; + ctx->left = str->length; + ctx->failed = false; + ctx->curKey = String_Empty; ctx->OnNewArray = Json_NullOnNew; ctx->OnNewObject = Json_NullOnNew; @@ -226,6 +226,18 @@ void LWebTask_Tick(struct LWebTask* task) { HttpRequest_Free(&req); } +void LWebTask_DisplayError(struct LWebTask* task, const char* action, String* dst) { + if (task->Res) { + /* Non HTTP error - this is not good */ + Logger_SysWarn(task->Res, action, Http_DescribeError); + String_Format2(dst, "&cError %i when %c", &task->Res, action); + } else if (task->Status != 200) { + String_Format2(dst, "&c%i error when %c", &task->Status, action); + } else { + String_Format1(dst, "&cEmpty response when %c", action); + } +} + /*########################################################################################################################* *-------------------------------------------------------GetTokenTask------------------------------------------------------* @@ -234,7 +246,7 @@ struct GetTokenTaskData GetTokenTask; char tokenBuffer[STRING_SIZE]; static void GetTokenTask_OnValue(struct JsonContext* ctx, const String* str) { - if (!String_CaselessEqualsConst(&ctx->CurKey, "token")) return; + if (!String_CaselessEqualsConst(&ctx->curKey, "token")) return; String_Copy(&GetTokenTask.Token, str); } @@ -277,9 +289,9 @@ static void SignInTask_LogError(const String* str) { } static void SignInTask_OnValue(struct JsonContext* ctx, const String* str) { - if (String_CaselessEqualsConst(&ctx->CurKey, "username")) { + if (String_CaselessEqualsConst(&ctx->curKey, "username")) { String_Copy(&SignInTask.Username, str); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "errors")) { + } else if (String_CaselessEqualsConst(&ctx->curKey, "errors")) { SignInTask_LogError(str); } } @@ -321,46 +333,46 @@ struct FetchServerData FetchServerTask; static struct ServerInfo* curServer; static void ServerInfo_Init(struct ServerInfo* info) { - String_InitArray(info->Hash, info->_hashBuffer); - String_InitArray(info->Name, info->_nameBuffer); - String_InitArray(info->IP, info->_ipBuffer); + String_InitArray(info->hash, info->_hashBuffer); + String_InitArray(info->name, info->_nameBuffer); + String_InitArray(info->ip, info->_ipBuffer); - String_InitArray(info->Mppass, info->_mppassBuffer); - String_InitArray(info->Software, info->_softBuffer); - String_InitArray(info->Country, info->_countryBuffer); + String_InitArray(info->mppass, info->_mppassBuffer); + String_InitArray(info->software, info->_softBuffer); + String_InitArray(info->country, info->_countryBuffer); - info->Players = 0; - info->MaxPlayers = 0; - info->Uptime = 0; - info->Featured = false; + info->players = 0; + info->maxPlayers = 0; + info->uptime = 0; + info->featured = false; info->_order = -100000; } static void ServerInfo_Parse(struct JsonContext* ctx, const String* val) { struct ServerInfo* info = curServer; - if (String_CaselessEqualsConst(&ctx->CurKey, "hash")) { - String_Copy(&info->Hash, val); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "name")) { - String_Copy(&info->Name, val); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "players")) { - Convert_ParseInt(val, &info->Players); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "maxplayers")) { - Convert_ParseInt(val, &info->MaxPlayers); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "uptime")) { - Convert_ParseInt(val, &info->Uptime); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "mppass")) { - String_Copy(&info->Mppass, val); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "ip")) { - String_Copy(&info->IP, val); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "port")) { - Convert_ParseInt(val, &info->Port); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "software")) { - String_Copy(&info->Software, val); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "featured")) { - Convert_ParseBool(val, &info->Featured); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "country_abbr")) { + if (String_CaselessEqualsConst(&ctx->curKey, "hash")) { + String_Copy(&info->hash, val); + } else if (String_CaselessEqualsConst(&ctx->curKey, "name")) { + String_Copy(&info->name, val); + } else if (String_CaselessEqualsConst(&ctx->curKey, "players")) { + Convert_ParseInt(val, &info->players); + } else if (String_CaselessEqualsConst(&ctx->curKey, "maxplayers")) { + Convert_ParseInt(val, &info->maxPlayers); + } else if (String_CaselessEqualsConst(&ctx->curKey, "uptime")) { + Convert_ParseInt(val, &info->uptime); + } else if (String_CaselessEqualsConst(&ctx->curKey, "mppass")) { + String_Copy(&info->mppass, val); + } else if (String_CaselessEqualsConst(&ctx->curKey, "ip")) { + String_Copy(&info->ip, val); + } else if (String_CaselessEqualsConst(&ctx->curKey, "port")) { + Convert_ParseInt(val, &info->port); + } else if (String_CaselessEqualsConst(&ctx->curKey, "software")) { + String_Copy(&info->software, val); + } else if (String_CaselessEqualsConst(&ctx->curKey, "featured")) { + Convert_ParseBool(val, &info->featured); + } else if (String_CaselessEqualsConst(&ctx->curKey, "country_abbr")) { /* Two letter country codes, see ISO 3166-1 alpha-2 */ - String_Copy(&info->Country, val); + String_Copy(&info->country, val); } } @@ -460,11 +472,11 @@ CC_NOINLINE static TimeMS CheckUpdateTask_ParseTime(const String* str) { } static void CheckUpdateTask_OnValue(struct JsonContext* ctx, const String* str) { - if (String_CaselessEqualsConst(&ctx->CurKey, "release_version")) { + if (String_CaselessEqualsConst(&ctx->curKey, "release_version")) { String_Copy(&CheckUpdateTask.LatestRelease, str); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "latest_ts")) { + } else if (String_CaselessEqualsConst(&ctx->curKey, "latest_ts")) { CheckUpdateTask.DevTimestamp = CheckUpdateTask_ParseTime(str); - } else if (String_CaselessEqualsConst(&ctx->CurKey, "release_ts")) { + } else if (String_CaselessEqualsConst(&ctx->curKey, "release_ts")) { CheckUpdateTask.RelTimestamp = CheckUpdateTask_ParseTime(str); } } diff --git a/src/LWeb.h b/src/LWeb.h index d41855c3b..c9759ea80 100644 --- a/src/LWeb.h +++ b/src/LWeb.h @@ -12,10 +12,10 @@ typedef void (*JsonOnNew)(struct JsonContext* ctx); /* State for parsing JSON text */ struct JsonContext { - char* Cur; /* Pointer to current character in JSON stream being inspected. */ - int Left; /* Number of characters left to be inspected. */ - bool Failed; /* Whether there was an error parsing the JSON. */ - String CurKey; /* Key/Name of current member */ + char* cur; /* Pointer to current character in JSON stream being inspected. */ + int left; /* Number of characters left to be inspected. */ + bool failed; /* Whether there was an error parsing the JSON. */ + String curKey; /* Key/Name of current member */ JsonOnNew OnNewArray; /* Invoked when start of an array is read. */ JsonOnNew OnNewObject; /* Invoked when start of an object is read. */ @@ -31,9 +31,9 @@ void Json_Parse(struct JsonContext* ctx); /* Represents all known details about a server. */ struct ServerInfo { - String Hash, Name, IP, Mppass, Software, Country; - int Players, MaxPlayers, Port, Uptime; - bool Featured; + String hash, name, ip, mppass, software, country; + int players, maxPlayers, port, uptime; + bool featured; int _order; /* (internal) order in servers table after filtering */ char _hashBuffer[32], _nameBuffer[STRING_SIZE]; char _ipBuffer[16], _mppassBuffer[STRING_SIZE]; @@ -55,6 +55,7 @@ struct LWebTask { void (*Handle)(uint8_t* data, uint32_t len); }; void LWebTask_Tick(struct LWebTask* task); +void LWebTask_DisplayError(struct LWebTask* task, const char* action, String* dst); extern struct GetTokenTaskData { diff --git a/src/LWidgets.c b/src/LWidgets.c index 983f6dd63..d224b8d54 100644 --- a/src/LWidgets.c +++ b/src/LWidgets.c @@ -634,26 +634,26 @@ void LSlider_Init(struct LSlider* w, int width, int height) { *------------------------------------------------------TableWidget--------------------------------------------------------* *#########################################################################################################################*/ static void FlagColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, int x, int y) { - Bitmap* bmp = Flags_Get(&row->Country); + Bitmap* bmp = Flags_Get(&row->country); if (bmp) Drawer2D_BmpCopy(&Launcher_Framebuffer, x + 2, y + 6, bmp); } static void NameColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, int x, int y) { - args->text = row->Name; + args->text = row->name; } static int NameColumn_Sort(const struct ServerInfo* a, const struct ServerInfo* b) { - return String_Compare(&b->Name, &a->Name); + return String_Compare(&b->name, &a->name); } static void PlayersColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, int x, int y) { - String_Format2(&args->text, "%i/%i", &row->Players, &row->MaxPlayers); + String_Format2(&args->text, "%i/%i", &row->players, &row->maxPlayers); } static int PlayersColumn_Sort(const struct ServerInfo* a, const struct ServerInfo* b) { - return b->Players - a->Players; + return b->players - a->players; } static void UptimeColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, int x, int y) { - int uptime = row->Uptime; + int uptime = row->uptime; char unit = 's'; if (uptime >= SECS_PER_DAY * 7) { @@ -666,14 +666,14 @@ static void UptimeColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, String_Format2(&args->text, "%i%r", &uptime, &unit); } static int UptimeColumn_Sort(const struct ServerInfo* a, const struct ServerInfo* b) { - return b->Uptime - a->Uptime; + return b->uptime - a->uptime; } static void SoftwareColumn_Draw(struct ServerInfo* row, struct DrawTextArgs* args, int x, int y) { - args->text = row->Software; + args->text = row->software; } static int SoftwareColumn_Sort(const struct ServerInfo* a, const struct ServerInfo* b) { - return String_Compare(&b->Software, &a->Software); + return String_Compare(&b->software, &a->software); } static struct LTableColumn tableColumns[5] = { @@ -712,7 +712,7 @@ static int LTable_GetSelectedIndex(struct LTable* w) { for (row = 0; row < w->RowsCount; row++) { entry = LTable_Get(row); - if (String_CaselessEquals(w->SelectedHash, &entry->Hash)) return row; + if (String_CaselessEquals(w->SelectedHash, &entry->hash)) return row; } return -1; } @@ -723,7 +723,7 @@ static void LTable_SetSelectedTo(struct LTable* w, int index) { if (index >= w->RowsCount) index = w->RowsCount - 1; if (index < 0) index = 0; - String_Copy(w->SelectedHash, <able_Get(index)->Hash); + String_Copy(w->SelectedHash, <able_Get(index)->hash); LTable_ShowSelected(w); w->OnSelectedChanged(); } @@ -759,8 +759,8 @@ static BitmapCol LTable_RowCol(struct LTable* w, struct ServerInfo* row) { bool selected; if (row) { - selected = String_Equals(&row->Hash, w->SelectedHash); - if (row->Featured) { + selected = String_Equals(&row->hash, w->SelectedHash); + if (row->featured) { return selected ? featSelCol : featuredCol; } else if (selected) { return selectedCol; @@ -804,8 +804,8 @@ static void LTable_DrawGridlines(struct LTable* w) { x, w->Y + w->HdrHeight, w->Width, GRIDLINE_SIZE); for (i = 0; i < w->NumColumns; i++) { - x += w->Columns[i].Width; - if (!w->Columns[i].ColumnGridline) continue; + x += w->Columns[i].width; + if (!w->Columns[i].columnGridline) continue; Drawer2D_Clear(&Launcher_Framebuffer, Launcher_BackgroundCol, x, w->Y, GRIDLINE_SIZE, w->Height); @@ -829,13 +829,13 @@ static void LTable_DrawHeaders(struct LTable* w) { x = w->X; y = w->Y; for (i = 0; i < w->NumColumns; i++) { - args.text = String_FromReadonly(w->Columns[i].Name); + args.text = String_FromReadonly(w->Columns[i].name); Drawer2D_DrawClippedText(&Launcher_Framebuffer, &args, x + CELL_XOFFSET, y + HDR_YOFFSET, - w->Columns[i].Width - CELL_XPADDING); + w->Columns[i].width - CELL_XPADDING); - x += w->Columns[i].Width; - if (w->Columns[i].ColumnGridline) x += GRIDLINE_SIZE; + x += w->Columns[i].width; + if (w->Columns[i].columnGridline) x += GRIDLINE_SIZE; } } @@ -865,11 +865,11 @@ static void LTable_DrawRows(struct LTable* w) { if (args.text.length) { Drawer2D_DrawClippedText(&Launcher_Framebuffer, &args, x + CELL_XOFFSET, y + ROW_YOFFSET, - w->Columns[i].Width - CELL_XPADDING); + w->Columns[i].width - CELL_XPADDING); } - x += w->Columns[i].Width; - if (w->Columns[i].ColumnGridline) x += GRIDLINE_SIZE; + x += w->Columns[i].width; + if (w->Columns[i].columnGridline) x += GRIDLINE_SIZE; } } } @@ -930,8 +930,8 @@ static void LTable_MouseMove(void* widget, int deltaX, int deltaY, bool wasOver) if (!deltaX || x >= w->X + w->Width - 20) return; col = w->DraggingColumn; - w->Columns[col].Width += deltaX; - Math_Clamp(w->Columns[col].Width, 20, w->Width - 20); + w->Columns[col].width += deltaX; + Math_Clamp(w->Columns[col].width, 20, w->Width - 20); LWidget_Redraw(w); } } @@ -946,7 +946,7 @@ static void LTable_RowsClick(struct LTable* w) { /* double click on row to join */ if (w->_lastClick + 1000 >= now && row == w->_lastRow) { - Launcher_ConnectToServer(<able_Get(row)->Hash); + Launcher_ConnectToServer(<able_Get(row)->hash); } w->_lastRow = LTable_GetSelectedIndex(w); @@ -959,25 +959,25 @@ static void LTable_HeadersClick(struct LTable* w) { for (i = 0, x = w->X; i < w->NumColumns; i++) { /* clicked on gridline, begin dragging */ - if (mouseX >= (x - 8) && mouseX < (x + 8) && w->Columns[i].Interactable) { + if (mouseX >= (x - 8) && mouseX < (x + 8) && w->Columns[i].interactable) { w->DraggingColumn = i - 1; return; } - x += w->Columns[i].Width; - if (w->Columns[i].ColumnGridline) x += GRIDLINE_SIZE; + x += w->Columns[i].width; + if (w->Columns[i].columnGridline) x += GRIDLINE_SIZE; } for (i = 0, x = w->X; i < w->NumColumns; i++) { - if (mouseX >= x && mouseX < (x + w->Columns[i].Width) && w->Columns[i].Interactable) { + if (mouseX >= x && mouseX < (x + w->Columns[i].width) && w->Columns[i].interactable) { sortingCol = i; - w->Columns[i].InvertSort = !w->Columns[i].InvertSort; + w->Columns[i].invertSort = !w->Columns[i].invertSort; LTable_Sort(w); return; } - x += w->Columns[i].Width; - if (w->Columns[i].ColumnGridline) x += GRIDLINE_SIZE; + x += w->Columns[i].width; + if (w->Columns[i].columnGridline) x += GRIDLINE_SIZE; } } @@ -1085,7 +1085,7 @@ void LTable_ApplyFilter(struct LTable* w) { count = FetchServersTask.NumServers; for (i = 0, j = 0; i < count; i++) { - if (String_CaselessContains(&Servers_Get(i)->Name, w->Filter)) { + if (String_CaselessContains(&Servers_Get(i)->name, w->Filter)) { FetchServersTask.Servers[j++]._order = FetchServersTask.Orders[i]; } } @@ -1103,12 +1103,12 @@ static int LTable_SortOrder(const struct ServerInfo* a, const struct ServerInfo* int order; if (sortingCol >= 0) { order = tableColumns[sortingCol].SortOrder(a, b); - return tableColumns[sortingCol].InvertSort ? -order : order; + return tableColumns[sortingCol].invertSort ? -order : order; } /* Default sort order. (most active server, then by highest uptime) */ - if (a->Players != b->Players) return a->Players - b->Players; - return a->Uptime - b->Uptime; + if (a->players != b->players) return a->players - b->players; + return a->uptime - b->uptime; } static void LTable_QuickSort(int left, int right) { diff --git a/src/LWidgets.h b/src/LWidgets.h index 481b145e9..6e2f75f23 100644 --- a/src/LWidgets.h +++ b/src/LWidgets.h @@ -116,9 +116,9 @@ struct DrawTextArgs; struct LTableColumn { /* Name of this column. */ - const char* Name; + const char* name; /* Width of this column in pixels. */ - int Width; + int width; /* Draws the value of this column for the given row. */ /* If args.Text is changed to something, that text gets drawn afterwards. */ /* Most of the time that's all you need to do. */ @@ -126,12 +126,12 @@ struct LTableColumn { /* Returns sort order of two rows, based on value of this column in both rows. */ int (*SortOrder)(const struct ServerInfo* a, const struct ServerInfo* b); /* Whether a vertical gridline (and padding) appears after this. */ - bool ColumnGridline; + bool columnGridline; /* Whether user can interact with this column. */ /* Non-interactable columns can't be sorted/resized. */ - bool Interactable; + bool interactable; /* Whether to invert the order of row sorting. */ - bool InvertSort; + bool invertSort; }; /* Represents a table of server entries. */ diff --git a/src/Launcher.c b/src/Launcher.c index 7aa8c93c5..dbec323ff 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -45,18 +45,19 @@ CC_NOINLINE static void Launcher_StartFromInfo(struct ServerInfo* info) { String port; char portBuffer[STRING_INT_CHARS]; String_InitArray(port, portBuffer); - String_AppendInt(&port, info->Port); - Launcher_StartGame(&SignInTask.Username, &info->Mppass, &info->IP, &port, &info->Name); + String_AppendInt(&port, info->port); + Launcher_StartGame(&SignInTask.Username, &info->mppass, &info->ip, &port, &info->name); } bool Launcher_ConnectToServer(const String* hash) { - int i; struct ServerInfo* info; + String logMsg; + int i; if (!hash->length) return false; for (i = 0; i < FetchServersTask.NumServers; i++) { info = &FetchServersTask.Servers[i]; - if (!String_Equals(hash, &info->Hash)) continue; + if (!String_Equals(hash, &info->hash)) continue; Launcher_StartFromInfo(info); return true; @@ -71,18 +72,16 @@ bool Launcher_ConnectToServer(const String* hash) { Thread_Sleep(10); } - if (FetchServerTask.Server.Hash.length) { + if (FetchServerTask.Server.hash.length) { Launcher_StartFromInfo(&FetchServerTask.Server); return true; - } else if (FetchServerTask.Base.Res) { - Logger_SimpleWarn(FetchServerTask.Base.Res, "fetching server info"); - } else if (FetchServerTask.Base.Status != 200) { - /* TODO: Use a better dialog message.. */ - Logger_SimpleWarn(FetchServerTask.Base.Status, "fetching server info"); - } else { + } 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 true; + return false; } diff --git a/src/Server.c b/src/Server.c index 9cdd2636b..ecb4c6f5f 100644 --- a/src/Server.c +++ b/src/Server.c @@ -60,7 +60,7 @@ static void Server_CheckAsyncResources(void) { TexturePack_Extract_Req(&item); HttpRequest_Free(&item); } else if (item.Result) { - Chat_Add1("&cError %i when trying to download texture pack", &item.Result); + Logger_SysWarn(item.Result, "trying to download texture pack", Http_DescribeError); } else { int status = item.StatusCode; if (status == 200 || status == 304) return;