From 2e4098c07b3ac10e8abbb56f547be285f284598b Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 29 Nov 2021 22:10:49 +1100 Subject: [PATCH] Webclient: Add query parameter based on current time when downloading your own skin This ensures that you'll always get a non-cached skin the first time the skin is downloaded in the session (although subsequent downloads in the same session may be cached). This should mostly address issues about changing your own skin not showing up in webclient - now instead of having to wait a few hours for non-cached skin to eventually get downloaded, just have to quit and open the webclient again --- src/Entity.c | 5 ++++- src/Http.h | 3 ++- src/Http_Web.c | 9 +++++++++ src/_HttpBase.h | 4 ++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Entity.c b/src/Entity.c index 7cbbac7ed..8e79577c6 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -468,6 +468,7 @@ static void Entity_CheckSkin(struct Entity* e) { struct Stream mem; struct Bitmap bmp; cc_string skin; + cc_uint8 flags; cc_result res; /* Don't check skin if don't have to */ @@ -477,8 +478,10 @@ static void Entity_CheckSkin(struct Entity* e) { if (!e->SkinFetchState) { first = Entity_FirstOtherWithSameSkinAndFetchedSkin(e); + flags = e == &LocalPlayer_Instance ? HTTP_FLAG_NOCACHE : 0; + if (!first) { - e->_skinReqID = Http_AsyncGetSkin(&skin); + e->_skinReqID = Http_AsyncGetSkin(&skin, flags); e->SkinFetchState = SKIN_FETCH_DOWNLOADING; } else { Entity_CopySkin(e, first); diff --git a/src/Http.h b/src/Http.h index fe36314dc..eff04a8ac 100644 --- a/src/Http.h +++ b/src/Http.h @@ -12,6 +12,7 @@ struct StringsBuffer; #define URL_MAX_SIZE (STRING_SIZE * 2) #define HTTP_FLAG_PRIORITY 0x01 +#define HTTP_FLAG_NOCACHE 0x02 extern struct IGameComponent Http_Component; @@ -45,7 +46,7 @@ struct HttpRequest { /* Aschronously performs a http GET request to download a skin. */ /* If url is a skin, downloads from there. (if not, downloads from SKIN_SERVER/[skinName].png) */ -int Http_AsyncGetSkin(const cc_string* skinName); +int Http_AsyncGetSkin(const cc_string* skinName, cc_uint8 flags); /* Asynchronously performs a http GET request. (e.g. to download data) */ int Http_AsyncGetData(const cc_string* url, cc_uint8 flags); /* Asynchronously performs a http HEAD request. (e.g. to get Content-Length header) */ diff --git a/src/Http_Web.c b/src/Http_Web.c index 6b4e35eea..c1e9b4084 100644 --- a/src/Http_Web.c +++ b/src/Http_Web.c @@ -6,6 +6,7 @@ extern int interop_DownloadAsync(const char* url, int method, int reqID); extern int interop_IsHttpsOnly(void); static struct RequestList workingReqs, queuedReqs; +static cc_uint64 startTime; /*########################################################################################################################* @@ -117,6 +118,13 @@ EMSCRIPTEN_KEEPALIVE void Http_OnFinishedAsync(int reqID, void* data, int len, i /* Adds a req to the list of pending requests, waking up worker thread if needed */ static void HttpBackend_Add(struct HttpRequest* req, cc_uint8 flags) { + /* Add time based query string parameter to bypass browser cache */ + if (flags & HTTP_FLAG_NOCACHE) { + cc_string url = String_FromRawArray(req->url); + int lo = (int)(startTime), hi = (int)(startTime >> 32); + String_Format2(&url, "?t=%i%i", &hi, &lo); + } + RequestList_Append(&queuedReqs, req, flags); Http_StartNextDownload(); } @@ -129,6 +137,7 @@ static void Http_Init(void) { Http_InitCommon(); /* If this webpage is https://, browsers deny any http:// downloading */ httpsOnly = interop_IsHttpsOnly(); + startTime = DateTime_CurrentUTC_MS(); RequestList_Init(&queuedReqs); RequestList_Init(&workingReqs); diff --git a/src/_HttpBase.h b/src/_HttpBase.h index a06e6ada9..72739e0e1 100644 --- a/src/_HttpBase.h +++ b/src/_HttpBase.h @@ -208,7 +208,7 @@ static void Http_CleanCacheTask(struct ScheduledTask* task) { /*########################################################################################################################* *----------------------------------------------------Http public api------------------------------------------------------* *#########################################################################################################################*/ -int Http_AsyncGetSkin(const cc_string* skinName) { +int Http_AsyncGetSkin(const cc_string* skinName, cc_uint8 flags) { cc_string url; char urlBuffer[URL_MAX_SIZE]; String_InitArray(url, urlBuffer); @@ -217,7 +217,7 @@ int Http_AsyncGetSkin(const cc_string* skinName) { } else { String_Format2(&url, "%s/%s.png", &skinServer, skinName); } - return Http_AsyncGetData(&url, 0); + return Http_AsyncGetData(&url, flags); } int Http_AsyncGetData(const cc_string* url, cc_uint8 flags) {