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
This commit is contained in:
Spoike 2021-10-31 18:20:45 +00:00
parent d2937174bf
commit 3afbfc8547
5 changed files with 74 additions and 53 deletions

View file

@ -2331,7 +2331,7 @@ void CL_PakDownloads(int mode)
} }
else else
Q_strncpyz(local, pname, sizeof(local)); 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; int usage = 0;
qboolean alreadyhave = false; qboolean alreadyhave = false;
extern char *cl_dp_packagenames; extern char *cl_dp_packagenames;
unsigned int dlflags = DLLF_VERBOSE; unsigned int dlflags = DLLF_VERBOSE|DLLF_ALLOWWEB;
if (argc < 2) if (argc < 2)
{ {
Con_Printf("%s: No args\n", Cmd_Argv(0)); Con_Printf("%s: No args\n", Cmd_Argv(0));

View file

@ -548,8 +548,9 @@ qboolean CL_EnqueDownload(const char *filename, const char *localname, unsigned
downloadlist_t *dl; downloadlist_t *dl;
qboolean webdl = false; qboolean webdl = false;
char ext[8]; 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) if (!localname)
return false; 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. 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); 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. 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) else if (dl->status == DL_FINISHED)
{ {
@ -737,7 +738,7 @@ static void CL_SendDownloadStartRequest(char *filename, char *localname, unsigne
return; return;
#ifdef WEBCLIENT #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); struct dl_download *wdl = HTTP_CL_Get(filename, localname, CL_WebDownloadFinished);
if (wdl) if (wdl)
@ -977,12 +978,20 @@ qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localnam
if (flags & DLLF_ALLOWWEB) if (flags & DLLF_ALLOWWEB)
{ {
const char *sv_dlURL = InfoBuf_ValueForKey(&cl.serverinfo, "sv_dlURL"); extern cvar_t sv_dlURL;
flags &= ~DLLF_ALLOWWEB; const char *dlURL = InfoBuf_ValueForKey(&cl.serverinfo, "sv_dlURL");
if (*sv_dlURL && (flags & DLLF_NONGAME) && !strncmp(filename, "package/", 8)) if (!*dlURL)
{ dlURL = sv_dlURL.string;
filename = va("%s/%s", cl_download_mapsrc.string, filename+8); flags &= ~(DLLF_TRYWEB|DLLF_ALLOWWEB);
flags |= 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 && else if (*cl_download_mapsrc.string &&
!strcmp(filename, localname) && !strcmp(filename, localname) &&
@ -991,11 +1000,16 @@ qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localnam
{ {
char base[MAX_QPATH]; char base[MAX_QPATH];
COM_FileBase(filename, base, sizeof(base)); COM_FileBase(filename, base, sizeof(base));
if (!strncmp(cl_download_mapsrc.string, "http://", 7) || !strncmp(cl_download_mapsrc.string, "https://", 8)) #ifndef FTE_TARGET_WEB
filename = va("%s%s.bsp", cl_download_mapsrc.string, base); 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 else
filename = va("http://%s/%s.bsp", cl_download_mapsrc.string, base); #endif
flags |= DLLF_ALLOWWEB; 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; continue;
Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]); Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]);
if (!strncmp(cl.image_name[i], "../", 3)) //some servers are just awkward. 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 else
CL_CheckOrEnqueDownloadFile(picname, picname, 0); CL_CheckOrEnqueDownloadFile(picname, picname, DLLF_ALLOWWEB);
} }
if (!CLQ2_RegisterTEntModels()) if (!CLQ2_RegisterTEntModels())
return; return;
@ -1213,7 +1227,7 @@ static void Model_CheckDownloads (void)
continue; continue;
#endif #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); CL_CheckModelResources(s);
} }
@ -1228,7 +1242,7 @@ static void Model_CheckDownloads (void)
if (!*s) if (!*s)
continue; continue;
CL_CheckOrEnqueDownloadFile(s, s, 0); CL_CheckOrEnqueDownloadFile(s, s, DLLF_ALLOWWEB);
CL_CheckModelResources(s); CL_CheckModelResources(s);
} }
#endif #endif
@ -1576,7 +1590,7 @@ void Sound_CheckDownload(const char *s)
return; return;
#endif #endif
//download the one the server said. //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*/ /*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.sendprespawn || cls.state == ca_active)
{
if (cl.downloadlist) if (cl.downloadlist)
{ {
downloadlist_t *dl; downloadlist_t *dl;
@ -1663,7 +1678,7 @@ void CL_RequestNextDownload (void)
fl = dl->flags; fl = dl->flags;
/*if we don't require downloads don't queue requests until we're actually on the server, slightly more deterministic*/ /*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)) 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) if (cl.sendprespawn)
{ // get next signon phase { // get next signon phase
@ -4402,7 +4420,7 @@ static void CL_ParseModellist (qboolean lots)
SCR_SetLoadingFile("loading data"); 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... //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) if (cl.model_precache[1] && cl.model_precache[1]->loadstate == MLS_LOADED)
FS_LoadMapPackFile(cl.model_precache[1]->name, cl.model_precache[1]->archive); 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) if (i >= 1 && i < MAX_PRECACHE_MODELS)
{ {
model_t *model; 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); model = Mod_ForName(Mod_FixName(s, cl.model_name[1]), (i == 1)?MLV_ERROR:MLV_WARN);
// if (!model) // if (!model)
// Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); // Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
@ -6807,7 +6825,7 @@ static void CL_ParsePrecache(void)
{ {
sfx_t *sfx; sfx_t *sfx;
if (S_HaveOutput()) if (S_HaveOutput())
CL_CheckOrEnqueDownloadFile(va("sound/%s", s), NULL, 0); CL_CheckOrEnqueDownloadFile(va("sound/%s", s), NULL, DLLF_ALLOWWEB);
sfx = S_PrecacheSound (s); sfx = S_PrecacheSound (s);
// if (!sfx) // if (!sfx)
// Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); // Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);

View file

@ -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_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_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; enum dlfailreason_e failreason;
struct downloadlist_s *next; struct downloadlist_s *next;

View file

@ -78,7 +78,11 @@ extern cvar_t password;
#endif #endif
cvar_t spectator_password = CVARF("spectator_password", "", CVAR_NOUNSAFEEXPAND); // password for entering as a sepctator 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."); 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 = 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_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"); cvar_t allow_download_models = CVARD("allow_download_models", "1", "0 blocks downloading of any file in the progs/ or models/ directory");

View file

@ -789,13 +789,11 @@ mergeInto(LibraryManager.library,
}; };
var dcconfig = {ordered: false, maxRetransmits: 0, reliable:false}; 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: var s = {pc:null, ws:null, inq:[], err:0, con:0, isclient:clientside, callcb:
function(evtype,stringdata) function(evtype,stringdata)
{ //private helper { //private helper
console.log("emscriptenfte_rtc_create callback: " + evtype); //console.log("emscriptenfte_rtc_create callback: " + evtype);
var stringlen = (stringdata.length*3)+1; var stringlen = (stringdata.length*3)+1;
var dataptr = _malloc(stringlen); var dataptr = _malloc(stringlen);
@ -823,15 +821,15 @@ console.log("emscriptenfte_rtc_create callback: " + evtype);
s.ws.binaryType = 'arraybuffer'; s.ws.binaryType = 'arraybuffer';
s.ws.onclose = function(event) s.ws.onclose = function(event)
{ {
console.log("webrtc datachannel closed:") //console.log("webrtc datachannel closed:")
console.log(event); //console.log(event);
s.con = 0; s.con = 0;
s.err = 1; s.err = 1;
}; };
s.ws.onopen = function(event) s.ws.onopen = function(event)
{ {
console.log("webrtc datachannel opened:"); //console.log("webrtc datachannel opened:");
console.log(event); //console.log(event);
s.con = 1; s.con = 1;
}; };
s.ws.onmessage = function(event) s.ws.onmessage = function(event)
@ -844,8 +842,8 @@ console.log(event);
s.pc.onicecandidate = function(e) s.pc.onicecandidate = function(e)
{ {
console.log("onicecandidate: "); //console.log("onicecandidate: ");
console.log(e); //console.log(e);
var desc; var desc;
if (1) if (1)
desc = JSON.stringify(e.candidate); desc = JSON.stringify(e.candidate);
@ -855,18 +853,18 @@ console.log(e);
}; };
s.pc.oniceconnectionstatechange = function(e) s.pc.oniceconnectionstatechange = function(e)
{ {
console.log("oniceconnectionstatechange: "); //console.log("oniceconnectionstatechange: ");
console.log(e); //console.log(e);
}; };
s.pc.onaddstream = function(e) s.pc.onaddstream = function(e)
{ {
console.log("onaddstream: "); //console.log("onaddstream: ");
console.log(e); //console.log(e);
}; };
s.pc.ondatachannel = function(e) s.pc.ondatachannel = function(e)
{ {
console.log("ondatachannel: "); //console.log("ondatachannel: ");
console.log(e); //console.log(e);
s.recvchan = e.channel; s.recvchan = e.channel;
s.recvchan.binaryType = 'arraybuffer'; s.recvchan.binaryType = 'arraybuffer';
@ -875,8 +873,8 @@ console.log(e);
}; };
s.pc.onnegotiationneeded = function(e) s.pc.onnegotiationneeded = function(e)
{ {
console.log("onnegotiationneeded: "); //console.log("onnegotiationneeded: ");
console.log(e); //console.log(e);
}; };
if (clientside) if (clientside)
@ -885,8 +883,8 @@ console.log(e);
function(desc) function(desc)
{ {
s.pc.setLocalDescription(desc); s.pc.setLocalDescription(desc);
console.log("gotlocaldescription: "); // console.log("gotlocaldescription: ");
console.log(desc); // console.log(desc);
if (1) if (1)
desc = JSON.stringify(desc); desc = JSON.stringify(desc);
@ -897,8 +895,8 @@ console.log(e);
}, },
function(event) function(event)
{ {
console.log("createOffer error:"); // console.log("createOffer error:");
console.log(event); // console.log(event);
s.err = 1; s.err = 1;
} }
); );
@ -930,8 +928,8 @@ console.log(e);
function(desc) function(desc)
{ {
s.pc.setLocalDescription(desc); s.pc.setLocalDescription(desc);
console.log("gotlocaldescription: "); // console.log("gotlocaldescription: ");
console.log(desc); // console.log(desc);
if (1) if (1)
desc = JSON.stringify(desc); desc = JSON.stringify(desc);
@ -942,7 +940,7 @@ console.log(e);
}, },
function(event) function(event)
{ {
console.log("createAnswer error:" + event.toString()); // console.log("createAnswer error:" + event.toString());
s.err = 1; s.err = 1;
} }
); );
@ -962,8 +960,8 @@ console.log(e);
desc = JSON.parse(offer); desc = JSON.parse(offer);
else else
desc = {candidate:offer, sdpMid:null, sdpMLineIndex:0}; desc = {candidate:offer, sdpMid:null, sdpMLineIndex:0};
console.log("addIceCandidate:"); //console.log("addIceCandidate:");
console.log(desc); //console.log(desc);
s.pc.addIceCandidate(desc); s.pc.addIceCandidate(desc);
} catch(err) { console.log(err); } } catch(err) { console.log(err); }
}, },
@ -971,7 +969,7 @@ console.log(desc);
emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress) emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress)
{ {
var _url = UTF8ToString(url); var _url = UTF8ToString(url);
console.log("Attempting download of " + _url); // console.log("Attempting download of " + _url);
var http = new XMLHttpRequest(); var http = new XMLHttpRequest();
try try
{ {
@ -987,7 +985,7 @@ console.log(desc);
http.onload = function(e) http.onload = function(e)
{ {
console.log("onload: " + _url + " status " + http.status); //console.log("onload: " + _url + " status " + http.status);
if (http.status == 200) if (http.status == 200)
{ {
if (onload) if (onload)
@ -1002,7 +1000,7 @@ console.log("onload: " + _url + " status " + http.status);
http.onerror = function(e) http.onerror = function(e)
{ {
console.log("onerror: " + _url); //console.log("onerror: " + _url);
if (onerror) if (onerror)
{{{makeDynCall('vii')}}}(onerror, ctx, 0); {{{makeDynCall('vii')}}}(onerror, ctx, 0);
}; };