From 3afbfc85471845e51a6b3c25cd568711402d36a2 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 31 Oct 2021 18:20:45 +0000 Subject: [PATCH] Attempt to download missing files from the uri named by the local sv_dlURL setting, if specified, for easier demo playback. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6095 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 4 +-- engine/client/cl_parse.c | 62 ++++++++++++++++++++++++++-------------- engine/client/client.h | 1 + engine/server/sv_main.c | 4 +++ engine/web/ftejslib.js | 56 +++++++++++++++++------------------- 5 files changed, 74 insertions(+), 53 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index f2621d6f1..e904fe00f 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2331,7 +2331,7 @@ void CL_PakDownloads(int mode) } else Q_strncpyz(local, pname, sizeof(local)); - CL_CheckOrEnqueDownloadFile(pname, local, DLLF_NONGAME); + CL_CheckOrEnqueDownloadFile(pname, local, DLLF_ALLOWWEB|DLLF_NONGAME); } } @@ -4223,7 +4223,7 @@ static void CL_Curl_f(void) int usage = 0; qboolean alreadyhave = false; extern char *cl_dp_packagenames; - unsigned int dlflags = DLLF_VERBOSE; + unsigned int dlflags = DLLF_VERBOSE|DLLF_ALLOWWEB; if (argc < 2) { Con_Printf("%s: No args\n", Cmd_Argv(0)); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index ad6058eab..7a4d17e0b 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -548,8 +548,9 @@ qboolean CL_EnqueDownload(const char *filename, const char *localname, unsigned downloadlist_t *dl; qboolean webdl = false; char ext[8]; - if (!strncmp(filename, "http://", 7) || !strncmp(filename, "https://", 8)) + if ((flags & DLLF_TRYWEB) || !strncmp(filename, "http://", 7) || !strncmp(filename, "https://", 8)) { + flags |= DLLF_TRYWEB; if (!localname) return false; @@ -715,7 +716,7 @@ static void CL_WebDownloadFinished(struct dl_download *dl) else //other stuff is PROBABLY 403forbidden, but lets blame the server's config if its a tls issue etc. CL_DownloadFailed(dl->url, &dl->qdownload, DLFAIL_SERVERCVAR); if (dl->qdownload.flags & DLLF_ALLOWWEB) //re-enqueue it if allowed, but this time not from the web server. - CL_EnqueDownload(dl->qdownload.localname, dl->qdownload.localname, dl->qdownload.flags & ~DLLF_ALLOWWEB); + CL_EnqueDownload(dl->qdownload.localname, dl->qdownload.localname, dl->qdownload.flags & ~(DLLF_ALLOWWEB|DLLF_TRYWEB)); } else if (dl->status == DL_FINISHED) { @@ -737,7 +738,7 @@ static void CL_SendDownloadStartRequest(char *filename, char *localname, unsigne return; #ifdef WEBCLIENT - if (!strncmp(filename, "http://", 7) || !strncmp(filename, "https://", 8)) + if (flags & DLLF_TRYWEB) { struct dl_download *wdl = HTTP_CL_Get(filename, localname, CL_WebDownloadFinished); if (wdl) @@ -977,12 +978,20 @@ qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localnam if (flags & DLLF_ALLOWWEB) { - const char *sv_dlURL = InfoBuf_ValueForKey(&cl.serverinfo, "sv_dlURL"); - flags &= ~DLLF_ALLOWWEB; - if (*sv_dlURL && (flags & DLLF_NONGAME) && !strncmp(filename, "package/", 8)) - { - filename = va("%s/%s", cl_download_mapsrc.string, filename+8); - flags |= DLLF_ALLOWWEB; + extern cvar_t sv_dlURL; + const char *dlURL = InfoBuf_ValueForKey(&cl.serverinfo, "sv_dlURL"); + if (!*dlURL) + dlURL = sv_dlURL.string; + flags &= ~(DLLF_TRYWEB|DLLF_ALLOWWEB); + if (*dlURL && (flags & DLLF_NONGAME) && !strncmp(filename, "package/", 8)) + { //filename is something like: package/GAMEDIR/foo.pk3 + filename = va("%s/%s", dlURL, filename+8); + flags |= DLLF_TRYWEB|DLLF_ALLOWWEB; + } + else if (*dlURL) + { //we don't really know which gamedir its meant to be for... + filename = va("%s/%s/%s", dlURL, FS_GetGamedir(true), filename); + flags |= DLLF_TRYWEB|DLLF_ALLOWWEB; } else if (*cl_download_mapsrc.string && !strcmp(filename, localname) && @@ -991,11 +1000,16 @@ qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localnam { char base[MAX_QPATH]; COM_FileBase(filename, base, sizeof(base)); - if (!strncmp(cl_download_mapsrc.string, "http://", 7) || !strncmp(cl_download_mapsrc.string, "https://", 8)) - filename = va("%s%s.bsp", cl_download_mapsrc.string, base); +#ifndef FTE_TARGET_WEB + if (strncmp(cl_download_mapsrc.string, "http://", 7) && !strncmp(cl_download_mapsrc.string, "https://", 8)) + { + Con_Printf("%s: Scheme not specified.\n", cl_download_mapsrc.name); + filename = va("https://%s/%s", cl_download_mapsrc.string, filename+5); + } else - filename = va("http://%s/%s.bsp", cl_download_mapsrc.string, base); - flags |= DLLF_ALLOWWEB; +#endif + filename = va("%s%s", cl_download_mapsrc.string, filename+5); + flags |= DLLF_TRYWEB|DLLF_ALLOWWEB; } } @@ -1190,9 +1204,9 @@ static void Model_CheckDownloads (void) continue; Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]); if (!strncmp(cl.image_name[i], "../", 3)) //some servers are just awkward. - CL_CheckOrEnqueDownloadFile(picname, picname+8, 0); + CL_CheckOrEnqueDownloadFile(picname, picname+8, DLLF_ALLOWWEB); else - CL_CheckOrEnqueDownloadFile(picname, picname, 0); + CL_CheckOrEnqueDownloadFile(picname, picname, DLLF_ALLOWWEB); } if (!CLQ2_RegisterTEntModels()) return; @@ -1213,7 +1227,7 @@ static void Model_CheckDownloads (void) continue; #endif - CL_CheckOrEnqueDownloadFile(s, s, (i==1)?DLLF_REQUIRED|DLLF_ALLOWWEB:0); //world is required to be loaded. + CL_CheckOrEnqueDownloadFile(s, s, ((i==1)?DLLF_REQUIRED:0)|DLLF_ALLOWWEB); //world is required to be loaded. CL_CheckModelResources(s); } @@ -1228,7 +1242,7 @@ static void Model_CheckDownloads (void) if (!*s) continue; - CL_CheckOrEnqueDownloadFile(s, s, 0); + CL_CheckOrEnqueDownloadFile(s, s, DLLF_ALLOWWEB); CL_CheckModelResources(s); } #endif @@ -1576,7 +1590,7 @@ void Sound_CheckDownload(const char *s) return; #endif //download the one the server said. - CL_CheckOrEnqueDownloadFile(s, NULL, 0); + CL_CheckOrEnqueDownloadFile(s, NULL, DLLF_ALLOWWEB); } /* @@ -1639,6 +1653,7 @@ void CL_RequestNextDownload (void) /*request downloads only if we're at the point where we've received a complete list of them*/ if (cl.sendprespawn || cls.state == ca_active) + { if (cl.downloadlist) { downloadlist_t *dl; @@ -1663,7 +1678,7 @@ void CL_RequestNextDownload (void) fl = dl->flags; /*if we don't require downloads don't queue requests until we're actually on the server, slightly more deterministic*/ - if (cls.state == ca_active || (requiredownloads.value && !cls.demoplayback) || (fl & DLLF_REQUIRED)) + if (cls.state == ca_active || (requiredownloads.value && !(cls.demoplayback && !(fl&DLLF_TRYWEB))) || (fl & DLLF_REQUIRED)) { if ((fl & DLLF_OVERWRITE) || !CL_CheckFile (dl->localname)) { @@ -1682,6 +1697,9 @@ void CL_RequestNextDownload (void) } } } + else if (cls.download && requiredownloads.value) + return; + } if (cl.sendprespawn) { // get next signon phase @@ -4402,7 +4420,7 @@ static void CL_ParseModellist (qboolean lots) SCR_SetLoadingFile("loading data"); //we need to try to load it now if we can, so any embedded archive will be loaded *before* we start looking for other content... - cl.model_precache[1] = Mod_ForName (cl.model_name[1], MLV_WARNSYNC); + cl.model_precache[1] = Mod_ForName (cl.model_name[1], MLV_SILENT); if (cl.model_precache[1] && cl.model_precache[1]->loadstate == MLS_LOADED) FS_LoadMapPackFile(cl.model_precache[1]->name, cl.model_precache[1]->archive); @@ -6788,7 +6806,7 @@ static void CL_ParsePrecache(void) if (i >= 1 && i < MAX_PRECACHE_MODELS) { model_t *model; - CL_CheckOrEnqueDownloadFile(s, s, 0); + CL_CheckOrEnqueDownloadFile(s, s, DLLF_ALLOWWEB); model = Mod_ForName(Mod_FixName(s, cl.model_name[1]), (i == 1)?MLV_ERROR:MLV_WARN); // if (!model) // Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); @@ -6807,7 +6825,7 @@ static void CL_ParsePrecache(void) { sfx_t *sfx; if (S_HaveOutput()) - CL_CheckOrEnqueDownloadFile(va("sound/%s", s), NULL, 0); + CL_CheckOrEnqueDownloadFile(va("sound/%s", s), NULL, DLLF_ALLOWWEB); sfx = S_PrecacheSound (s); // if (!sfx) // Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); diff --git a/engine/client/client.h b/engine/client/client.h index 7ff9effe7..22d2e50ca 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -576,6 +576,7 @@ typedef struct downloadlist_s { #define DLLF_BEGUN (1u<<8) //server has confirmed that the file exists, is readable, and we've opened a file. should not be set on new requests. #define DLLF_ALLOWWEB (1u<<9) //failed http downloads should retry but from the game server itself +#define DLLF_TRYWEB (1u<<10) //should be trying to download it from a website... enum dlfailreason_e failreason; struct downloadlist_s *next; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index bee5a77a6..539621a7f 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -78,7 +78,11 @@ extern cvar_t password; #endif cvar_t spectator_password = CVARF("spectator_password", "", CVAR_NOUNSAFEEXPAND); // password for entering as a sepctator +#ifdef FTE_TARGET_WEB +cvar_t sv_dlURL = CVARAFD(/*ioq3*/"sv_dlURL", "", /*dp*/"sv_curl_defaulturl", CVAR_SERVERINFO|CVAR_NOSAVE, "Provides clients with an external url from which they can obtain pk3s/packages from an external http server instead of having to download over udp."); +#else cvar_t sv_dlURL = CVARAFD(/*ioq3*/"sv_dlURL", "", /*dp*/"sv_curl_defaulturl", CVAR_SERVERINFO|CVAR_ARCHIVE, "Provides clients with an external url from which they can obtain pk3s/packages from an external http server instead of having to download over udp."); +#endif cvar_t allow_download = CVARAD("allow_download", "1", /*q3*/"sv_allowDownload", "If 1, permits downloading. Set to 0 to unconditionally block *ALL* downloads from this server. You may wish to set sv_dlURL if you wish clients to still be able to download content."); cvar_t allow_download_skins = CVARD("allow_download_skins", "1", "0 blocks downloading of any file in the skins/ directory"); cvar_t allow_download_models = CVARD("allow_download_models", "1", "0 blocks downloading of any file in the progs/ or models/ directory"); diff --git a/engine/web/ftejslib.js b/engine/web/ftejslib.js index 368c41648..dfa0019b6 100644 --- a/engine/web/ftejslib.js +++ b/engine/web/ftejslib.js @@ -789,13 +789,11 @@ mergeInto(LibraryManager.library, }; var dcconfig = {ordered: false, maxRetransmits: 0, reliable:false}; -console.log("emscriptenfte_rtc_create"); - var s = {pc:null, ws:null, inq:[], err:0, con:0, isclient:clientside, callcb: function(evtype,stringdata) { //private helper -console.log("emscriptenfte_rtc_create callback: " + evtype); +//console.log("emscriptenfte_rtc_create callback: " + evtype); var stringlen = (stringdata.length*3)+1; var dataptr = _malloc(stringlen); @@ -823,15 +821,15 @@ console.log("emscriptenfte_rtc_create callback: " + evtype); s.ws.binaryType = 'arraybuffer'; s.ws.onclose = function(event) { -console.log("webrtc datachannel closed:") -console.log(event); +//console.log("webrtc datachannel closed:") +//console.log(event); s.con = 0; s.err = 1; }; s.ws.onopen = function(event) { -console.log("webrtc datachannel opened:"); -console.log(event); +//console.log("webrtc datachannel opened:"); +//console.log(event); s.con = 1; }; s.ws.onmessage = function(event) @@ -844,8 +842,8 @@ console.log(event); s.pc.onicecandidate = function(e) { -console.log("onicecandidate: "); -console.log(e); +//console.log("onicecandidate: "); +//console.log(e); var desc; if (1) desc = JSON.stringify(e.candidate); @@ -855,18 +853,18 @@ console.log(e); }; s.pc.oniceconnectionstatechange = function(e) { -console.log("oniceconnectionstatechange: "); -console.log(e); +//console.log("oniceconnectionstatechange: "); +//console.log(e); }; s.pc.onaddstream = function(e) { -console.log("onaddstream: "); -console.log(e); +//console.log("onaddstream: "); +//console.log(e); }; s.pc.ondatachannel = function(e) { -console.log("ondatachannel: "); -console.log(e); +//console.log("ondatachannel: "); +//console.log(e); s.recvchan = e.channel; s.recvchan.binaryType = 'arraybuffer'; @@ -875,8 +873,8 @@ console.log(e); }; s.pc.onnegotiationneeded = function(e) { -console.log("onnegotiationneeded: "); -console.log(e); +//console.log("onnegotiationneeded: "); +//console.log(e); }; if (clientside) @@ -885,8 +883,8 @@ console.log(e); function(desc) { s.pc.setLocalDescription(desc); - console.log("gotlocaldescription: "); - console.log(desc); +// console.log("gotlocaldescription: "); +// console.log(desc); if (1) desc = JSON.stringify(desc); @@ -897,8 +895,8 @@ console.log(e); }, function(event) { - console.log("createOffer error:"); - console.log(event); +// console.log("createOffer error:"); +// console.log(event); s.err = 1; } ); @@ -930,8 +928,8 @@ console.log(e); function(desc) { s.pc.setLocalDescription(desc); - console.log("gotlocaldescription: "); - console.log(desc); +// console.log("gotlocaldescription: "); +// console.log(desc); if (1) desc = JSON.stringify(desc); @@ -942,7 +940,7 @@ console.log(e); }, function(event) { - console.log("createAnswer error:" + event.toString()); +// console.log("createAnswer error:" + event.toString()); s.err = 1; } ); @@ -962,8 +960,8 @@ console.log(e); desc = JSON.parse(offer); else desc = {candidate:offer, sdpMid:null, sdpMLineIndex:0}; -console.log("addIceCandidate:"); -console.log(desc); +//console.log("addIceCandidate:"); +//console.log(desc); s.pc.addIceCandidate(desc); } catch(err) { console.log(err); } }, @@ -971,7 +969,7 @@ console.log(desc); emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress) { var _url = UTF8ToString(url); - console.log("Attempting download of " + _url); +// console.log("Attempting download of " + _url); var http = new XMLHttpRequest(); try { @@ -987,7 +985,7 @@ console.log(desc); http.onload = function(e) { -console.log("onload: " + _url + " status " + http.status); +//console.log("onload: " + _url + " status " + http.status); if (http.status == 200) { if (onload) @@ -1002,7 +1000,7 @@ console.log("onload: " + _url + " status " + http.status); http.onerror = function(e) { -console.log("onerror: " + _url); +//console.log("onerror: " + _url); if (onerror) {{{makeDynCall('vii')}}}(onerror, ctx, 0); };