diff --git a/src/LScreens.c b/src/LScreens.c index b9ccc5b68..5cb74ccf9 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -924,7 +924,7 @@ static void MainScreen_TickGetToken(struct MainScreen* s) { return; } - if (String_CaselessEquals(&GetTokenTask.username, &s->iptUsername.text)) { + if (!GetTokenTask.error && String_CaselessEquals(&GetTokenTask.username, &s->iptUsername.text)) { /* Already logged in, go straight to fetching servers */ MainScreen_LoginPhase2(s, &GetTokenTask.username); } else { diff --git a/src/LWeb.c b/src/LWeb.c index 1a8f2304f..4113e606b 100644 --- a/src/LWeb.c +++ b/src/LWeb.c @@ -9,6 +9,8 @@ #include "Options.h" #include "PackedCol.h" #include "Errors.h" +#include "Game.h" +#include "Utils.h" /*########################################################################################################################* *----------------------------------------------------------JSON-----------------------------------------------------------* @@ -239,6 +241,8 @@ static void GetTokenTask_OnValue(struct JsonContext* ctx, const cc_string* str) String_Copy(&GetTokenTask.token, str); } else if (String_CaselessEqualsConst(&ctx->curKey, "username")) { String_Copy(&GetTokenTask.username, str); + } else if (String_CaselessEqualsConst(&ctx->curKey, "errors")) { + if (str->length) GetTokenTask.error = true; } } @@ -255,6 +259,7 @@ void GetTokenTask_Run(void) { LWebTask_Reset(&GetTokenTask.Base); String_InitArray(GetTokenTask.token, tokenBuffer); String_InitArray(GetTokenTask.username, userBuffer); + GetTokenTask.error = false; GetTokenTask.Base.Handle = GetTokenTask_Handle; GetTokenTask.Base.reqID = Http_AsyncGetDataEx(&url, false, NULL, NULL, &ccCookies); @@ -416,6 +421,7 @@ static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) { int count; Mem_Free(FetchServersTask.servers); Mem_Free(FetchServersTask.orders); + Session_Save(); FetchServersTask.numServers = 0; FetchServersTask.servers = NULL; @@ -533,7 +539,7 @@ void FetchUpdateTask_Run(cc_bool release, cc_bool d3d9) { /*########################################################################################################################* -*-----------------------------------------------------FetchFlagsTask-----------------------------------------------------* +*-----------------------------------------------------FetchFlagsTask------------------------------------------------------* *#########################################################################################################################*/ struct FetchFlagsData FetchFlagsTask; static int flagsCount, flagsCapacity; @@ -639,4 +645,32 @@ void Flags_Free(void) { flagsCount = 0; FetchFlagsTask.count = 0; } + + +/*########################################################################################################################* +*------------------------------------------------------Session cache------------------------------------------------------* +*#########################################################################################################################*/ +static cc_string sessionKey = String_FromConst("session"); +static cc_bool loadedSession; + +void Session_Load(void) { + cc_string session; char buffer[3072]; + if (loadedSession) return; + loadedSession = true; + /* Increase from max 512 to 2048 per entry */ + StringsBuffer_SetLengthBits(&ccCookies, 11); + + String_InitArray(session, buffer); + Options_GetSecure(LOPT_SESSION, &session, &Game_Username); + if (!session.length) return; + EntryList_Set(&ccCookies, &sessionKey, &session, '='); +} + +void Session_Save(void) { +#ifdef CC_BUILD_WIN + cc_string session = EntryList_UNSAFE_Get(&ccCookies, &sessionKey, '='); + if (!session.length) return; + Options_SetSecure(LOPT_SESSION, &session, &Game_Username); +#endif +} #endif diff --git a/src/LWeb.h b/src/LWeb.h index 00490830f..e183eb703 100644 --- a/src/LWeb.h +++ b/src/LWeb.h @@ -59,6 +59,7 @@ extern struct GetTokenTaskData { struct LWebTask Base; cc_string token; /* Random CSRF token for logging in. */ cc_string username; /* Username if session is already logged in. */ + cc_bool error; /* Whether a signin error occurred */ } GetTokenTask; void GetTokenTask_Run(void); @@ -118,4 +119,7 @@ void FetchFlagsTask_Add(const struct ServerInfo* server); struct Bitmap* Flags_Get(const struct ServerInfo* server); /* Frees all flag bitmaps. */ void Flags_Free(void); + +void Session_Load(void); +void Session_Save(void); #endif diff --git a/src/Launcher.c b/src/Launcher.c index d3ea9c761..71f2049b9 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -299,6 +299,8 @@ void Launcher_Run(void) { Drawer2D_BlackTextShadows = true; InitFramebuffer(); + Options_UNSAFE_Get("launcher-cc-username", &Game_Username); + Session_Load(); Launcher_LoadSkin(); Launcher_Init(); Launcher_TryLoadTexturePack(); diff --git a/src/Options.c b/src/Options.c index be3676b44..a7cf3ac26 100644 --- a/src/Options.c +++ b/src/Options.c @@ -33,6 +33,8 @@ static cc_bool Options_LoadFilter(const cc_string* entry) { } void Options_Load(void) { + /* Increase from max 512 to 2048 per entry */ + StringsBuffer_SetLengthBits(&Options, 11); EntryList_Load(&Options, "options-default.txt", '=', NULL); EntryList_Load(&Options, "options.txt", '=', NULL); } diff --git a/src/Options.h b/src/Options.h index f93cb80bc..8e96fb632 100644 --- a/src/Options.h +++ b/src/Options.h @@ -72,6 +72,8 @@ #define OPT_TOUCH_SCALE "gui-touchscale" #define OPT_HTTP_ONLY "http-no-https" +#define LOPT_SESSION "launcher-session" + struct StringsBuffer; extern struct StringsBuffer Options; /* Frees any memory allocated in storing options. */ diff --git a/src/String.c b/src/String.c index 5592fe4f0..1fdcb9a5e 100644 --- a/src/String.c +++ b/src/String.c @@ -756,7 +756,6 @@ cc_bool Convert_ParseBool(const cc_string* str, cc_bool* value) { *------------------------------------------------------StringsBuffer------------------------------------------------------* *#########################################################################################################################*/ #define STRINGSBUFFER_BUFFER_EXPAND_SIZE 8192 -#define STRINGSBUFFER_DEFAULT_LEN_SHIFT 9 #define StringsBuffer_GetOffset(raw) ((raw) >> buffer->_lenShift) #define StringsBuffer_GetLength(raw) ((raw) & buffer->_lenMask) @@ -771,7 +770,7 @@ CC_NOINLINE static void StringsBuffer_Init(struct StringsBuffer* buffer) { buffer->_flagsCapacity = STRINGSBUFFER_FLAGS_DEF_ELEMS; if (buffer->_lenShift) return; - StringsBuffer_SetLengthBits(buffer, STRINGSBUFFER_DEFAULT_LEN_SHIFT); + StringsBuffer_SetLengthBits(buffer, STRINGSBUFFER_DEF_LEN_SHIFT); } void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits) { diff --git a/src/String.h b/src/String.h index 0daf94e42..5d72060bd 100644 --- a/src/String.h +++ b/src/String.h @@ -207,7 +207,8 @@ CC_API cc_bool Convert_ParseBool(const cc_string* str, cc_bool* value); #define STRINGSBUFFER_BUFFER_DEF_SIZE 4096 #define STRINGSBUFFER_FLAGS_DEF_ELEMS 256 -#define STRINGSBUFFER_LEN_MASK 0x1FFUL +#define STRINGSBUFFER_DEF_LEN_SHIFT 9 +#define STRINGSBUFFER_DEF_LEN_MASK 0x1FFUL struct StringsBuffer { char* textBuffer; /* Raw characters of all entries */ @@ -223,6 +224,8 @@ struct StringsBuffer { int _lenMask; }; +/* Sets the number of bits in an entry's flags that are used to store its length. */ +/* (e.g. if bits is 9, then the maximum length of an entry is 2^9-1 = 511) */ void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits); /* Resets counts to 0, and frees any allocated memory. */ CC_NOINLINE void StringsBuffer_Clear(struct StringsBuffer* buffer); diff --git a/src/Utils.c b/src/Utils.c index 59095e727..8f1c9c52d 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -225,16 +225,16 @@ int Convert_FromBase64(const char* src, int len, cc_uint8* dst) { *#########################################################################################################################*/ void EntryList_Load(struct StringsBuffer* list, const char* file, char separator, EntryList_Filter filter) { cc_string entry; char entryBuffer[768]; - cc_string path; char pathBuffer[FILENAME_SIZE]; + cc_string path; cc_string key, value; - int lineLen; + int lineLen, maxLen; cc_uint8 buffer[2048]; struct Stream stream, buffered; cc_result res; - String_InitArray(path, pathBuffer); - String_AppendConst(&path, file); + path = String_FromReadonly(file); + maxLen = list->_lenMask ? list->_lenMask : STRINGSBUFFER_DEF_LEN_MASK; res = Stream_OpenFile(&stream, &path); if (res == ReturnCode_FileNotFound) return; @@ -258,7 +258,7 @@ void EntryList_Load(struct StringsBuffer* list, const char* file, char separator /* Sometimes file becomes corrupted and replaced with NULL */ /* If don't prevent this here, client aborts in StringsBuffer_Add */ - if (entry.length > STRINGSBUFFER_LEN_MASK) { + if (entry.length > maxLen) { lineLen = entry.length; entry.length = 0; String_Format2(&entry, "Skipping very long (%i characters) line in %c, file may be corrupted", &lineLen, file);