chunked downloads are in
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@791 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
8e8d12ac19
commit
890bc1f637
3 changed files with 197 additions and 75 deletions
|
@ -973,8 +973,6 @@ void CL_SendCmd (void)
|
|||
return;
|
||||
}
|
||||
|
||||
CL_SendDownloadReq();
|
||||
|
||||
if (msecstouse > 255)
|
||||
msecstouse = 255;
|
||||
|
||||
|
@ -998,6 +996,9 @@ void CL_SendCmd (void)
|
|||
buf.cursize = 0;
|
||||
buf.data = data;
|
||||
clientcount = cl.splitclients;
|
||||
|
||||
CL_SendDownloadReq(&buf);
|
||||
|
||||
if (!clientcount)
|
||||
clientcount = 1;
|
||||
if (1) //wait for server data before sending clc_move stuff? nope, mvdsv doesn't like that.
|
||||
|
|
|
@ -101,6 +101,7 @@ cvar_t model = {"model", "", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
|||
cvar_t topcolor = {"topcolor", "", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
||||
cvar_t bottomcolor = {"bottomcolor", "", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
||||
cvar_t rate = {"rate", "2500", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
||||
cvar_t drate = {"drate", "100000", NULL, CVAR_ARCHIVE | CVAR_USERINFO}; // :)
|
||||
cvar_t noaim = {"noaim", "", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
||||
cvar_t msg = {"msg", "1", NULL, CVAR_ARCHIVE | CVAR_USERINFO};
|
||||
cvar_t cl_nofake = {"cl_nofake", "2"};
|
||||
|
@ -346,6 +347,9 @@ void CL_SendConnectPacket (
|
|||
// fteprotextsupported |= PEXT_64PLAYERS;
|
||||
fteprotextsupported |= PEXT_SHOWPIC;
|
||||
fteprotextsupported |= PEXT_SETATTACHMENT;
|
||||
#ifdef PEXT_CHUNKEDDOWNLOADS
|
||||
fteprotextsupported |= PEXT_CHUNKEDDOWNLOADS;
|
||||
#endif
|
||||
|
||||
fteprotextsupported &= ftepext;
|
||||
|
||||
|
@ -430,11 +434,11 @@ void CL_SendConnectPacket (
|
|||
strcat(data, va(" %i %i", cls.qport, cls.challenge));
|
||||
|
||||
//userinfo 0 + zquake extension info.
|
||||
strcat(data, va(" \"%s\\*z_ext\\%i\"", cls.userinfo, SUPPORTED_EXTENSIONS));
|
||||
strcat(data, va(" \"%s\\*z_ext\\%i\"", cls.userinfo, SUPPORTED_Z_EXTENSIONS));
|
||||
for (c = 1; c < clients; c++)
|
||||
{
|
||||
Info_SetValueForStarKey (playerinfo2, "name", va("%s%i", name.string, c+1), MAX_INFO_STRING);
|
||||
strcat(data, va(" \"%s\"", playerinfo2, SUPPORTED_EXTENSIONS));
|
||||
strcat(data, va(" \"%s\"", playerinfo2, SUPPORTED_Z_EXTENSIONS));
|
||||
}
|
||||
|
||||
strcat(data, "\n");
|
||||
|
@ -2086,7 +2090,10 @@ void CL_Download_f (void)
|
|||
cls.downloadtype = dl_single;
|
||||
}
|
||||
|
||||
|
||||
CL_EnqueDownload(url, true, false);
|
||||
|
||||
/*
|
||||
strcpy(cls.downloadname, url);
|
||||
|
||||
_snprintf (cls.downloadname, sizeof(cls.downloadname), "%s/%s", com_gamedir, url);
|
||||
|
||||
|
@ -2103,13 +2110,15 @@ void CL_Download_f (void)
|
|||
break;
|
||||
}
|
||||
|
||||
strcpy(cls.downloadtempname, cls.downloadname);
|
||||
COM_StripExtension(cls.downloadname, cls.downloadtempname);
|
||||
COM_DefaultExtension(cls.downloadtempname, ".tmp");
|
||||
if (cls.down
|
||||
// cls.downloadqw = fopen (cls.downloadname, "wb");
|
||||
cls.downloadmethod = DL_QW;
|
||||
cls.downloadmethod = DL_QWPENDING;
|
||||
|
||||
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
SZ_Print (&cls.netchan.message, va("download %s\n",url));
|
||||
SZ_Print (&cls.netchan.message, va("download %s\n",url));*/
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
@ -2271,6 +2280,7 @@ void CL_Init (void)
|
|||
Cvar_Register (&topcolor, cl_controlgroup);
|
||||
Cvar_Register (&bottomcolor, cl_controlgroup);
|
||||
Cvar_Register (&rate, cl_controlgroup);
|
||||
Cvar_Register (&drate, cl_controlgroup);
|
||||
Cvar_Register (&msg, cl_controlgroup);
|
||||
Cvar_Register (&noaim, cl_controlgroup);
|
||||
|
||||
|
|
|
@ -566,27 +566,9 @@ qboolean CL_EnqueDownload(char *filename, qboolean verbose, qboolean ignorefaile
|
|||
return true;
|
||||
}
|
||||
|
||||
void CL_SendDownloadRequest(char *filename)
|
||||
void CL_DisenqueDownload(char *filename)
|
||||
{
|
||||
downloadlist_t *dl, *nxt;
|
||||
|
||||
strcpy (cls.downloadname, filename);
|
||||
Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadname);
|
||||
|
||||
// download to a temp name, and only rename
|
||||
// to the real name when done, so if interrupted
|
||||
// a runt file wont be left
|
||||
COM_StripExtension (cls.downloadname, cls.downloadtempname);
|
||||
strcat (cls.downloadtempname, ".tmp");
|
||||
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
|
||||
|
||||
//prevent ftp/http from changing stuff
|
||||
cls.downloadmethod = DL_QWPENDING;
|
||||
cls.downloadpercent = 0;
|
||||
|
||||
|
||||
if(cl.downloadlist) //remove from enqued download list
|
||||
{
|
||||
if (!strcmp(cl.downloadlist->name, filename))
|
||||
|
@ -611,13 +593,59 @@ void CL_SendDownloadRequest(char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
void CL_SendDownloadRequest(char *filename)
|
||||
{
|
||||
strcpy (cls.downloadname, filename);
|
||||
Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadname);
|
||||
|
||||
// download to a temp name, and only rename
|
||||
// to the real name when done, so if interrupted
|
||||
// a runt file wont be left
|
||||
COM_StripExtension (cls.downloadname, cls.downloadtempname);
|
||||
strcat (cls.downloadtempname, ".tmp");
|
||||
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
|
||||
|
||||
//prevent ftp/http from changing stuff
|
||||
cls.downloadmethod = DL_QWPENDING;
|
||||
cls.downloadpercent = 0;
|
||||
|
||||
CL_DisenqueDownload(filename);
|
||||
}
|
||||
|
||||
//Do any reloading for the file that just reloaded.
|
||||
void CL_FinishDownload(char *filename)
|
||||
void CL_FinishDownload(char *filename, char *tempname)
|
||||
{
|
||||
int i;
|
||||
extern int mod_numknown;
|
||||
extern model_t mod_known[];
|
||||
|
||||
COM_RefreshFSCache_f();
|
||||
|
||||
cls.downloadmethod = DL_NONE;
|
||||
|
||||
// rename the temp file to it's final name
|
||||
if (tempname)
|
||||
{
|
||||
char oldn[MAX_OSPATH], newn[MAX_OSPATH];
|
||||
if (strcmp(tempname, filename))
|
||||
{
|
||||
if (strncmp(tempname,"skins/",6))
|
||||
{
|
||||
sprintf (oldn, "%s/%s", com_gamedir, tempname);
|
||||
sprintf (newn, "%s/%s", com_gamedir, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (oldn, "qw/%s", tempname);
|
||||
sprintf (newn, "qw/%s", filename);
|
||||
}
|
||||
if (rename (oldn, newn))
|
||||
Con_TPrintf (TL_RENAMEFAILED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(filename, "gfx/palette.lmp"))
|
||||
{
|
||||
Cbuf_AddText("vid_restart\n", RESTRICT_LOCAL);
|
||||
|
@ -646,8 +674,6 @@ to start a download from the server.
|
|||
*/
|
||||
qboolean CL_CheckOrDownloadFile (char *filename, int nodelay)
|
||||
{
|
||||
downloadlist_t *failed;
|
||||
|
||||
if (strstr (filename, ".."))
|
||||
{
|
||||
Con_TPrintf (TL_NORELATIVEPATHS);
|
||||
|
@ -925,6 +951,11 @@ void CL_RequestNextDownload (void)
|
|||
{
|
||||
if (!COM_FCheckExists (cl.downloadlist->name))
|
||||
CL_SendDownloadRequest(cl.downloadlist->name);
|
||||
else
|
||||
{
|
||||
Con_Printf("Already have %s\n", cl.downloadlist->name);
|
||||
CL_DisenqueDownload(cl.downloadlist->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (cls.downloadtype)
|
||||
|
@ -947,8 +978,8 @@ void CL_RequestNextDownload (void)
|
|||
}
|
||||
}
|
||||
|
||||
void CL_RequestADownloadChunk(void);
|
||||
void CL_SendDownloadReq(void)
|
||||
int CL_RequestADownloadChunk(void);
|
||||
void CL_SendDownloadReq(sizebuf_t *msg)
|
||||
{
|
||||
if (cl.downloadlist && !cls.downloadmethod)
|
||||
{
|
||||
|
@ -959,7 +990,16 @@ void CL_SendDownloadReq(void)
|
|||
#ifdef PEXT_CHUNKEDDOWNLOADS
|
||||
if (cls.downloadmethod == DL_QWCHUNKS)
|
||||
{
|
||||
CL_RequestADownloadChunk();
|
||||
int i = CL_RequestADownloadChunk();
|
||||
if (i < 0)
|
||||
{
|
||||
//we can stop downloading now.
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteByte(msg, clc_stringcmd);
|
||||
MSG_WriteString(msg, va("nextdl %i\n", i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -1011,17 +1051,33 @@ char *ZLibDownloadDecode(int *messagesize, char *input, int finalsize)
|
|||
}
|
||||
#endif
|
||||
|
||||
void CL_DownloadFailed(void);
|
||||
void CL_DownloadFailed(char *name)
|
||||
{
|
||||
//add this to our failed list. (so we don't try downloading it again...)
|
||||
downloadlist_t *failed;
|
||||
failed = Z_Malloc(sizeof(downloadlist_t));
|
||||
failed->next = cl.faileddownloads;
|
||||
cl.faileddownloads = failed;
|
||||
Q_strncpyz(failed->name, name, sizeof(failed->name));
|
||||
|
||||
cls.downloadmethod = DL_NONE;
|
||||
}
|
||||
|
||||
float downloadstarttime;
|
||||
#ifdef PEXT_CHUNKEDDOWNLOADS
|
||||
#define MAXBLOCKS 64
|
||||
int downloadblock;
|
||||
#define MAXBLOCKS 64 //must be power of 2
|
||||
#define DLBLOCKSIZE 1024
|
||||
int downloadsize;
|
||||
int receivedbytes;
|
||||
int recievedblock[MAXBLOCKS];
|
||||
int firstblock;
|
||||
int blockcycle;
|
||||
void CL_ParseChunkedDownload(void)
|
||||
{
|
||||
qbyte *name;
|
||||
int totalsize;
|
||||
int chunknum;
|
||||
char data[DLBLOCKSIZE];
|
||||
|
||||
chunknum = MSG_ReadLong();
|
||||
if (chunknum < 0)
|
||||
|
@ -1038,7 +1094,7 @@ void CL_ParseChunkedDownload(void)
|
|||
else
|
||||
Con_Printf("Couldn't find file %s on the server\n", name);
|
||||
|
||||
CL_DownloadFailed();
|
||||
CL_DownloadFailed(name);
|
||||
|
||||
CL_RequestNextDownload();
|
||||
return;
|
||||
|
@ -1050,28 +1106,108 @@ void CL_ParseChunkedDownload(void)
|
|||
//start the new download
|
||||
cls.downloadmethod = DL_QWCHUNKS;
|
||||
cls.downloadpercent = 0;
|
||||
downloadsize = totalsize;
|
||||
|
||||
downloadstarttime = Sys_DoubleTime();
|
||||
|
||||
strcpy(cls.downloadname, name);
|
||||
COM_StripExtension(name, cls.downloadtempname);
|
||||
COM_DefaultExtension(cls.downloadtempname, ".tmp");
|
||||
|
||||
if (!strncmp(cls.downloadtempname,"skins/",6))
|
||||
sprintf (name, "qw/%s", cls.downloadtempname); //skins go to quake/qw/skins. never quake/gamedir/skins (blame id)
|
||||
else
|
||||
sprintf (name, "%s/%s", com_gamedir, cls.downloadtempname);
|
||||
COM_CreatePath (name);
|
||||
cls.downloadqw = fopen (name, "wb");
|
||||
|
||||
firstblock = 0;
|
||||
receivedbytes = 0;
|
||||
blockcycle = -1; //so it requests 0 first. :)
|
||||
memset(recievedblock, 0, sizeof(recievedblock));
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf("Received dl block %i: ", chunknum);
|
||||
|
||||
MSG_ReadData(data, DLBLOCKSIZE);
|
||||
|
||||
if (cls.demoplayback)
|
||||
{
|
||||
|
||||
{ //err, yeah, when playing demos we don't actually pay any attention to this.
|
||||
return;
|
||||
}
|
||||
if (chunknum < firstblock)
|
||||
{
|
||||
Con_Printf("too old\n", chunknum);
|
||||
return;
|
||||
}
|
||||
if (chunknum-firstblock >= MAXBLOCKS)
|
||||
{
|
||||
Con_Printf("^1too new!\n", chunknum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (recievedblock[chunknum&(MAXBLOCKS-1)])
|
||||
{
|
||||
Con_Printf("duplicated\n", chunknum);
|
||||
return;
|
||||
}
|
||||
Con_Printf("usable\n", chunknum);
|
||||
receivedbytes+=DLBLOCKSIZE;
|
||||
recievedblock[chunknum&(MAXBLOCKS-1)] = true;
|
||||
|
||||
while(recievedblock[firstblock&(MAXBLOCKS-1)])
|
||||
{
|
||||
recievedblock[firstblock&(MAXBLOCKS-1)] = false;
|
||||
firstblock++;
|
||||
}
|
||||
|
||||
fseek(cls.downloadqw, chunknum*DLBLOCKSIZE, SEEK_SET);
|
||||
if (downloadsize - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve.
|
||||
fwrite(data, 1, downloadsize - chunknum*DLBLOCKSIZE, cls.downloadqw);
|
||||
else
|
||||
fwrite(data, 1, DLBLOCKSIZE, cls.downloadqw);
|
||||
|
||||
cls.downloadpercent = receivedbytes/(float)downloadsize*100;
|
||||
}
|
||||
|
||||
void CL_RequestADownloadChunk(void)
|
||||
int CL_RequestADownloadChunk(void)
|
||||
{
|
||||
int i;
|
||||
int b;
|
||||
|
||||
if (cls.downloadmethod != DL_QWCHUNKS)
|
||||
{
|
||||
Con_Printf("download not initiated\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
blockcycle++;
|
||||
for (i = 0; i < MAXBLOCKS; i++)
|
||||
{
|
||||
b = ((i+blockcycle)&(MAXBLOCKS-1))
|
||||
+ firstblock;
|
||||
if (!recievedblock[b&(MAXBLOCKS-1)]) //don't ask for ones we've already got.
|
||||
{
|
||||
if (b >= (downloadsize+DLBLOCKSIZE-1)/DLBLOCKSIZE) //don't ask for blocks that are over the size of the file.
|
||||
continue;
|
||||
Con_Printf("Requesting block %i\n", b);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf("^1 EOF?\n");
|
||||
|
||||
fclose(cls.downloadqw);
|
||||
CL_FinishDownload(cls.downloadname, cls.downloadtempname);
|
||||
|
||||
*cls.downloadname = '\0';
|
||||
cls.downloadqw = NULL;
|
||||
cls.downloadpercent = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CL_RequestDownloadPacket(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1085,10 +1221,8 @@ void CL_ParseDownload (void)
|
|||
{
|
||||
int size, percent;
|
||||
qbyte name[1024];
|
||||
int r;
|
||||
|
||||
#ifdef PEXT_CHUNKEDDOWNLOADS
|
||||
#pragma message fixme
|
||||
if (cls.fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)
|
||||
{
|
||||
CL_ParseChunkedDownload();
|
||||
|
@ -1130,13 +1264,8 @@ void CL_ParseDownload (void)
|
|||
Z_Free(cl.downloadlist);
|
||||
cl.downloadlist = next;
|
||||
}
|
||||
{ //add this to our failed list. (so we don't try downloading it again...)
|
||||
downloadlist_t *failed;
|
||||
failed = Z_Malloc(sizeof(downloadlist_t));
|
||||
failed->next = cl.faileddownloads;
|
||||
cl.faileddownloads = failed;
|
||||
Q_strncpyz(failed->name, cls.downloadname, sizeof(failed->name));
|
||||
}
|
||||
|
||||
CL_DownloadFailed(cls.downloadname);
|
||||
|
||||
CL_RequestNextDownload ();
|
||||
return;
|
||||
|
@ -1160,6 +1289,8 @@ void CL_ParseDownload (void)
|
|||
CL_RequestNextDownload ();
|
||||
return;
|
||||
}
|
||||
|
||||
downloadstarttime = Sys_DoubleTime();
|
||||
SCR_EndLoadingPlaque();
|
||||
}
|
||||
#ifdef PEXT_ZLIBDL
|
||||
|
@ -1194,35 +1325,15 @@ void CL_ParseDownload (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
char oldn[MAX_OSPATH];
|
||||
char newn[MAX_OSPATH];
|
||||
|
||||
fclose (cls.downloadqw);
|
||||
|
||||
// rename the temp file to it's final name
|
||||
if (strcmp(cls.downloadtempname, cls.downloadname)) {
|
||||
if (strncmp(cls.downloadtempname,"skins/",6)) {
|
||||
sprintf (oldn, "%s/%s", com_gamedir, cls.downloadtempname);
|
||||
sprintf (newn, "%s/%s", com_gamedir, cls.downloadname);
|
||||
} else {
|
||||
sprintf (oldn, "qw/%s", cls.downloadtempname);
|
||||
sprintf (newn, "qw/%s", cls.downloadname);
|
||||
}
|
||||
r = rename (oldn, newn);
|
||||
if (r)
|
||||
Con_TPrintf (TL_RENAMEFAILED);
|
||||
}
|
||||
|
||||
COM_RefreshFSCache_f();
|
||||
|
||||
cls.downloadmethod = DL_NONE;
|
||||
|
||||
CL_FinishDownload(cls.downloadname);
|
||||
|
||||
CL_FinishDownload(cls.downloadname, cls.downloadtempname);
|
||||
*cls.downloadname = '\0';
|
||||
cls.downloadqw = NULL;
|
||||
cls.downloadpercent = 0;
|
||||
|
||||
Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
|
||||
|
||||
// get another file if needed
|
||||
|
||||
CL_RequestNextDownload ();
|
||||
|
|
Loading…
Reference in a new issue