#include "fs.h"
#include "libcurl.h"
-static cvar_t cl_curl_maxdownloads = {1, "cl_curl_maxdownloads","1", "maximum number of concurrent HTTP/FTP downloads"};
-static cvar_t cl_curl_maxspeed = {1, "cl_curl_maxspeed","100", "maximum download speed (KiB/s)"};
-static cvar_t sv_curl_defaulturl = {1, "sv_curl_defaulturl","", "default autodownload source URL"};
-static cvar_t sv_curl_serverpackages = {1, "sv_curl_serverpackages","", "list of required files for the clients, separated by spaces"};
-static cvar_t cl_curl_enabled = {1, "cl_curl_enabled","0", "whether client's download support is enabled"};
+static cvar_t cl_curl_maxdownloads = {CVAR_SAVE, "cl_curl_maxdownloads","1", "maximum number of concurrent HTTP/FTP downloads"};
+static cvar_t cl_curl_maxspeed = {CVAR_SAVE, "cl_curl_maxspeed","100", "maximum download speed (KiB/s)"};
+static cvar_t sv_curl_defaulturl = {CVAR_SAVE, "sv_curl_defaulturl","", "default autodownload source URL"};
+static cvar_t sv_curl_serverpackages = {CVAR_SAVE, "sv_curl_serverpackages","", "list of required files for the clients, separated by spaces"};
+static cvar_t cl_curl_enabled = {CVAR_SAVE, "cl_curl_enabled","1", "whether client's download support is enabled"};
/*
=================================================================
static downloadinfo *downloads = NULL;
static int numdownloads = 0;
+static qboolean noclear = FALSE;
+
static int numdownloads_fail = 0;
static int numdownloads_success = 0;
static int numdownloads_added = 0;
void Curl_Clear_forthismap()
{
downloadinfo *di;
+ if(noclear)
+ return;
for(di = downloads; di; di = di->next)
di->forthismap = false;
Curl_CommandWhenError(NULL);
numdownloads_added = 0;
}
-/* obsolete: numdownloads_added contains the same
-static qboolean Curl_Have_forthismap()
+/*
+====================
+Curl_Have_forthismap
+
+Returns true if a download needed for the current game is running.
+====================
+*/
+qboolean Curl_Have_forthismap()
{
- downloadinfo *di;
- for(di = downloads; di; di = di->next)
- if(di->forthismap)
- return true;
- return false;
+ return numdownloads_added;
+}
+
+void Curl_Register_predownload()
+{
+ Curl_CommandWhenDone("cl_begindownloads");
+ Curl_CommandWhenError("cl_begindownloads");
}
-*/
/*
====================
return;
if(numdownloads_added && (numdownloads_success == numdownloads_added) && *command_when_done)
{
- Con_DPrintf("Map downloads occurred, executing %s\n", command_when_done);
+ Con_DPrintf("cURL downloads occurred, executing %s\n", command_when_done);
Cbuf_AddText("\n");
Cbuf_AddText(command_when_done);
Cbuf_AddText("\n");
- Curl_Clear_forthismap(NULL);
+ Curl_Clear_forthismap();
}
else if(numdownloads_added && numdownloads_fail && *command_when_error)
{
- Con_DPrintf("Map downloads FAILED, executing %s\n", command_when_error);
+ Con_DPrintf("cURL downloads FAILED, executing %s\n", command_when_error);
Cbuf_AddText("\n");
Cbuf_AddText(command_when_error);
Cbuf_AddText("\n");
- Curl_Clear_forthismap(NULL);
+ Curl_Clear_forthismap();
}
}
#if defined(WIN64)
"libcurl64.dll",
#elif defined(WIN32)
+ "libcurl-4.dll",
"libcurl-3.dll",
#elif defined(MACOSX)
+ "libcurl.4.dylib", // Mac OS X Notyetreleased
"libcurl.3.dylib", // Mac OS X Tiger
"libcurl.2.dylib", // Mac OS X Panther
#else
+ "libcurl.so.4",
"libcurl.so.3",
+ "libcurl.so", // FreeBSD
#endif
NULL
};
++numdownloads_fail;
}
Z_Free(di);
-
- Curl_CheckCommandWhenDone();
}
/*
return;
}
}
-
+
if(ispak && FS_FileExists(fn))
{
qboolean already_loaded;
*/
void Curl_Run()
{
+ noclear = FALSE;
+
if(!cl_curl_enabled.integer)
return;
if(!curl_dll)
return;
+ Curl_CheckCommandWhenDone();
+
if(!downloads)
return;
{
int remaining;
CURLMcode mc;
-
+
do
{
mc = qcurl_multi_perform(curlm, &remaining);
break;
}
}
-
+
Curl_EndDownload(di, failed, result);
}
}
else
{
downloadinfo *di = Curl_Find(url);
- Curl_EndDownload(di, CURL_DOWNLOAD_ABORTED, CURLE_OK);
+ if(di)
+ Curl_EndDownload(di, CURL_DOWNLOAD_ABORTED, CURLE_OK);
+ else
+ Con_Print("download not found\n");
}
return;
}
char donecommand[256];
if(cls.netcon)
{
- dpsnprintf(donecommand, sizeof(donecommand), "connect %s", cls.netcon->address);
- Curl_CommandWhenDone(donecommand);
+ if(cl.loadbegun) // curling won't inhibit loading the map any more when at this stage, so bail out and force a reconnect
+ {
+ dpsnprintf(donecommand, sizeof(donecommand), "connect %s", cls.netcon->address);
+ Curl_CommandWhenDone(donecommand);
+ noclear = TRUE;
+ CL_Disconnect();
+ noclear = FALSE;
+ Curl_CheckCommandWhenDone();
+ }
+ else
+ Curl_Register_predownload();
}
- CL_Disconnect();
-
- Curl_CheckCommandWhenDone();
}
return;
}
}
++i;
}
-
+
if(additional_info)
{
// TODO: can I clear command_when_done as soon as the first download fails?
if(*command_when_done && !numdownloads_fail && numdownloads_added)
{
- if(strncmp(command_when_done, "connect ", 8))
- dpsnprintf(addinfo, sizeof(addinfo), "(will do '%s' when done)", command_when_done);
- else
+ if(!strncmp(command_when_done, "connect ", 8))
dpsnprintf(addinfo, sizeof(addinfo), "(will join %s when done)", command_when_done + 8);
+ else if(!strcmp(command_when_done, "cl_begindownloads"))
+ dpsnprintf(addinfo, sizeof(addinfo), "(will enter the game when done)");
+ else
+ dpsnprintf(addinfo, sizeof(addinfo), "(will do '%s' when done)", command_when_done);
*additional_info = addinfo;
}
else
char *p = buf;
char *pattern = NULL, *patternend = NULL, *url = NULL, *urlend = NULL;
qboolean eof = false;
-
+
pattern = p;
while(!eof)
{
}
p = sv_curl_serverpackages.string;
Con_DPrintf("Require all of: %s\n", p);
- while(COM_ParseTokenConsole(&p))
+ while(COM_ParseToken_Simple(&p, false, false))
{
Con_DPrintf("Require: %s\n", com_token);
Curl_RequireFile(com_token);