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