if (cls.state == ca_dedicated)
return;
+ Curl_Clear_forthismap();
+
Con_DPrintf("CL_Disconnect\n");
CL_VM_ShutDown();
#include "cdaudio.h"
#include "cl_collision.h"
#include "csprogs.h"
+#include "libcurl.h"
char *svc_strings[128] =
{
if (cls.protocol == PROTOCOL_QUAKEWORLD)
return;
- // TODO: this would be a good place to do curl downloads
+ // this would be a good place to do curl downloads
+ if(Curl_Have_forthismap())
+ {
+ Curl_Register_predownload(); // come back later
+ return;
+ }
+
+ // if we got here...
+ // curl is done, so let's start with the business
+ cl.loadbegun = true;
if (cl.downloadcsqc)
{
void CL_BeginDownloads_f(void)
{
- CL_BeginDownloads(false);
+ // prevent cl_begindownloads from being issued multiple times in one match
+ // to prevent accidentally cancelled downloads
+ if(cl.loadbegun)
+ Con_DPrintf("cl_begindownloads is only valid once per match\n");
+ else
+ CL_BeginDownloads(false);
}
void CL_StopDownload(int size, int crc)
MSG_WriteString(&cls.netcon->message, va("soundlist %i %i", cl.qw_servercount, 0));
}
+ cl.loadbegun = false;
cl.loadfinished = false;
cls.state = ca_connected;
cl.downloadsound_current = 1;
cl.loadsound_total = numsounds;
cl.downloadcsqc = true;
+ cl.loadbegun = false;
cl.loadfinished = false;
}
ent = &cl.static_entities[cl.num_static_entities++];
CL_ParseBaseline (ent, large);
+ if (ent->state_baseline.modelindex == 0)
+ {
+ Con_DPrintf("svc_parsestatic: static entity without model at %f %f %f\n", ent->state_baseline.origin[0], ent->state_baseline.origin[1], ent->state_baseline.origin[2]);
+ cl.num_static_entities--;
+ // This is definitely a cheesy way to conserve resources...
+ return;
+ }
+
// copy it to the current state
ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, ent->state_baseline.origin[0], ent->state_baseline.origin[1], ent->state_baseline.origin[2], ent->state_baseline.angles[0], ent->state_baseline.angles[1], ent->state_baseline.angles[2], 1);
CL_UpdateRenderEntity(&ent->render);
-
- // This is definitely a cheesy way to conserve resources...
- //if (ent->render.model == NULL)
- // cl.num_static_entities--;
}
/*
int downloadsound_current;
int loadsound_total;
qboolean downloadcsqc;
+ qboolean loadbegun;
qboolean loadfinished;
// quakeworld stuff
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");
}
-*/
/*
====================
++numdownloads_fail;
}
Z_Free(di);
-
- Curl_CheckCommandWhenDone();
}
/*
*/
void Curl_Run()
{
+ noclear = FALSE;
+
if(!cl_curl_enabled.integer)
return;
if(!curl_dll)
return;
+ Curl_CheckCommandWhenDone();
+
if(!downloads)
return;
char donecommand[256];
if(cls.netcon)
{
- dpsnprintf(donecommand, sizeof(donecommand), "connect %s", cls.netcon->address);
- Curl_CommandWhenDone(donecommand);
+ if(cls.signon >= 3)
+ {
+ 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;
}
// 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
void Curl_Shutdown();
void Curl_CancelAll();
void Curl_Clear_forthismap();
+qboolean Curl_Have_forthismap();
+void Curl_Register_predownload();
void Curl_ClearRequirements();
void Curl_RequireFile(const char *filename);
MSG_WriteString (&client->netconnection->message, "cl_serverextension_download 1");
}
+ // send at this time so it's guaranteed to get executed at the right time
+ {
+ client_t *save;
+ save = host_client;
+ host_client = client;
+ Curl_SendRequirements();
+ host_client = save;
+ }
+
MSG_WriteByte (&client->netconnection->message, svc_serverinfo);
MSG_WriteLong (&client->netconnection->message, Protocol_NumberForEnum(sv.protocol));
MSG_WriteByte (&client->netconnection->message, svs.maxclients);
MSG_WriteByte (&client->netconnection->message, svc_signonnum);
MSG_WriteByte (&client->netconnection->message, 1);
- {
- client_t *save;
- save = host_client;
- host_client = client;
- Curl_SendRequirements();
- host_client = save;
- }
-
client->spawned = false; // need prespawn, spawn, etc
}