In-Game HTTP/FTP Downloads

Tony J. White tjw at webteam.net
Wed Aug 30 11:10:41 EDT 2006


https://bugzilla.icculus.org/show_bug.cgi?id=2661

(please see my latest patch there)

I would like to commit this change to SVN.  Speak now or forever hold your
peace. 

OVERVIEW
--------
This patch adds HTTP/FTP "redirected" download functionality to the ioquake3
client.  This feature is very desirable since the UDP downloads tend to
be so slow.  cURL was used (http://curl.haxx.se) for the downloading.
The feature is completely optional and makes no protocol change.

CVARS
-----
cl_cURLLib (default depends on system e.g. "libcurl.dylib")
	This is used when ioquake3 is built with USE_CURL_DLOPEN=1
	It is the name of the curl library that should be dlopen()'ed

cl_wwwDownload (default 1)
	When non-zero, the client will use cURL for downloading IF the server 
	allows it and cl_allowDownload is non-zero

sv_wwwBaseURL (default "")
	Set this to the "base" of the ftp:// or http:// URL that contains
	the paks used on the server.  The missing pak name (including 
	the fs_game dir) is appended to this string.  For example, if
	the file "baseq3/mymap.pk3" is missing and sv_wwwBaseURL is
	"http://tjw.org", then the client may attempt to download
	"http://tjw.org/baseq3/mymap.pk3" 

sv_wwwDownload (default 0)
	When set to non-zero, a client connecting to this server may use cURL
	for downloading provided sv_allowDownload is non-zero and 
	sv_wwwBaseURL is not an empty string.

CVAR NOTES
----------
sv_wwwBaseURL and sv_wwwDownload are CVAR_SERVERINFO cvars.  This means they
are put into the CS_SERVERINFO config string which is notorious for overflowing
since server admins tend to use the "sets" command to put way to much info
into this strings 1024 bytes.  I think the functionality of this feature is
worth the possible incompatability with old configs.  Without adding any
"sets" commands, a vanilla config will only use < 400 bytes of the 1024.

One big benefit of using CS_SERVERINFO is that unmodified servers can enable
this download functionality by using the "sets" command.

sv_wwwDownload is not CVAR_ARCHIVE.  sv_allowDownload is not CVAR_ARCHIVE
either so I just followed suit assuming there is a good reason for this.  


MODE OF OPERATION
-----------------
1. On connect, client parses sv_allowDownlod, sv_wwwDownload, and
   sv_wwwBasePath out of CS_SERVERINFO and copies the values into clc.
   variables.
2. When paks are required, the client will attempt to use cURL if the
   following is met:
     1) cl_wwwDownload is non-zero
     2) clc.sv_allowDownload is non-zero
     3) clc.sv_wwwDownload is non-zero
     4) clc.sv_wwwBaseURL is non-empty
     5) libcurl can be loaded in the case of USE_CURL_DLOPEN=1

   Otherwise it reverts to normal UDP download operations.

3. If a download can be started, the cURL connection is set up and the
   client sends a "disconnect" command to the server.

4. Once a cURL download has been started (and this is the hacky part),
   CL_Frame() is hijacked.  The only the operations from CL_Frame() that
   are run are those that will update the screen.  This is done to provide
   full ui.qvm compatability since the ui needs cls.state to be CA_CONNECTED
   in order to draw the download status screen.  Having cls.state set higher
   than CA_DISCONNECTED makes the client communicate with the server.  This
   solution seemed less hacky that trying to constantly flip cls.state to
   CA_CONNECTED when the ui call was made. 

5. When a download completes successfully, the client will move on to the next
   required missing pak, and if none exist, it will cleanup curl (and 
   unload it in the case of USE_CURL_DLOPEN=1).   The client will then 
   call CL_Reconnect_f()

6. If an error occured in the download process, then Com_Error() will show
   the curl strerror, repsonse code, and URL that was attempted.


BUILD NOTES
-----------

I've only added Makefile support for this for mingw, linux, and darwin since
that's all I have to test.

Here are the env vars for make:

	USE_CURL (default 1)
		disable all cURL support.

	USE_CURL_DLOPEN (default 1 except on mingw)
		Use dynamic loading of the library pointed to by the cvar
		cl_cURLLib

Also this feature respects the env var USE_LOCAL_HEADERS.

The mingw build is set to build against a static libcurl (which is included
at code/libs/win32/libcurl.a) by default. 





More information about the quake3 mailing list