add support for COMPRESSED downloads!!! Of course, both client and server must

both support this. The client tells the server it can support compressed
downloads by setting the z flag in the *cap userinfo. If the server detects
that the client supports compression, and the file to be downloaded is
compressed (more accurately, has the .gz extension), the server sends a special
download packet with a size of -2 (-1 indicates error),, percent of 0, followed
by the new name of the file (eg maps/foo.bsp.gz for maps/foo.bsp). The client
WILL NOT accept a new filename that doesn not match the old name for the length
of the old name. The client also will not accept a new name if there are . or
.. path components. If the client rejects the new name, it prints a warning
message and aborts that download.
This commit is contained in:
Bill Currie 2000-09-28 06:11:55 +00:00
parent 1a7f2af4ec
commit 1aa9084aa9
5 changed files with 83 additions and 34 deletions

View file

@ -49,6 +49,7 @@ extern char com_gamedir[MAX_OSPATH];
extern char gamedirfile[MAX_OSPATH];
void COM_WriteFile (char *filename, void *data, int len);
int _COM_FOpenFile (char *filename, QFile **gzfile, char *foundname, int zip);
int COM_FOpenFile (char *filename, QFile **gzfile);
void COM_CloseFile (QFile *h);
int COM_filelength (QFile *f);

View file

@ -1139,10 +1139,14 @@ void CL_Init (void)
Info_SetValueForKey (cls.userinfo, "bottomcolor", "0", MAX_INFO_STRING);
Info_SetValueForKey (cls.userinfo, "rate", "2500", MAX_INFO_STRING);
Info_SetValueForKey (cls.userinfo, "msg", "1", MAX_INFO_STRING);
// sprintf (st, "%s-%04d", QW_VERSION, build_number());
sprintf (st, "%s", QW_VERSION);
// sprintf (st, "%s-%04d", QW_VERSION, build_number());
sprintf (st, "%s", QW_VERSION);
Info_SetValueForStarKey (cls.userinfo, "*ver", st, MAX_INFO_STRING);
Info_SetValueForStarKey (cls.userinfo, "stdver", QSG_VERSION, MAX_INFO_STRING);
Info_SetValueForStarKey (cls.userinfo, "stdver", QSG_VERSION, MAX_INFO_STRING);
// set the capabilities info. single char flags (possibly with modifiefs)
// defined capabilities:
// z client can accept gzipped files.
Info_SetValueForStarKey (cls.userinfo, "*cap", "z", MAX_INFO_STRING);
CL_InitInput ();
CL_InitTEnts ();

View file

@ -377,11 +377,9 @@ void CL_ParseDownload (void)
return; // not in demo playback
}
if (size == -1)
{
if (size == -1) {
Con_Printf ("File not found.\n");
if (cls.download)
{
if (cls.download) {
Con_Printf ("cls.download shouldn't have been set\n");
Qclose (cls.download);
cls.download = NULL;
@ -390,9 +388,27 @@ void CL_ParseDownload (void)
return;
}
if (size == -2) {
char *newname = MSG_ReadString();
if (strncmp (newname, cls.downloadname, strlen(cls.downloadname))
|| strstr(newname, "/../")
|| strstr(newname, "/./")) {
Con_Printf ("WARNING: server tried to give a strange new name: %s\n",
newname);
CL_RequestNextDownload ();
return;
}
if (cls.download) {
Qclose (cls.download);
unlink (cls.downloadname);
}
strncpy (cls.downloadname, newname, sizeof (cls.downloadname));
Con_Printf ("downloading to %s\n", cls.downloadname);
return;
}
// open the file if not opened yet
if (!cls.download)
{
if (!cls.download) {
if (strncmp(cls.downloadtempname,"skins/",6))
snprintf (name, sizeof(name), "%s/%s", com_gamedir, cls.downloadtempname);
else
@ -401,8 +417,7 @@ void CL_ParseDownload (void)
COM_CreatePath (name);
cls.download = Qopen (name, "wb");
if (!cls.download)
{
if (!cls.download) {
msg_readcount += size;
Con_Printf ("Failed to open %s\n", cls.downloadtempname);
CL_RequestNextDownload ();
@ -413,14 +428,12 @@ void CL_ParseDownload (void)
Qwrite (cls.download, net_message.data + msg_readcount, size);
msg_readcount += size;
if (percent != 100)
{
if (percent != 100) {
// change display routines by zoid
// request next block
#if 0
Con_Printf (".");
if (10*(percent/10) != cls.downloadpercent)
{
if (10*(percent/10) != cls.downloadpercent) {
cls.downloadpercent = 10*(percent/10);
Con_Printf ("%i%%", cls.downloadpercent);
}
@ -429,9 +442,7 @@ void CL_ParseDownload (void)
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "nextdl");
}
else
{
} else {
char oldn[MAX_OSPATH];
char newn[MAX_OSPATH];

View file

@ -370,7 +370,7 @@ COM_CopyFile (char *netpath, char *cachepath)
COM_OpenRead
*/
QFile *
COM_OpenRead (const char *path, int offs, int len)
COM_OpenRead (const char *path, int offs, int len, int zip)
{
int fd=open(path,O_RDONLY);
unsigned char id[2];
@ -386,14 +386,16 @@ COM_OpenRead (const char *path, int offs, int len)
lseek(fd,0,SEEK_SET);
}
lseek(fd,offs,SEEK_SET);
read(fd,id,2);
if (id[0]==0x1f && id[1]==0x8b) {
lseek(fd,offs+len-4,SEEK_SET);
read(fd,len_bytes,4);
len=((len_bytes[3]<<24)
|(len_bytes[2]<<16)
|(len_bytes[1]<<8)
|(len_bytes[0]));
if (zip) {
read(fd,id,2);
if (id[0]==0x1f && id[1]==0x8b) {
lseek(fd,offs+len-4,SEEK_SET);
read(fd,len_bytes,4);
len=((len_bytes[3]<<24)
|(len_bytes[2]<<16)
|(len_bytes[1]<<8)
|(len_bytes[0]));
}
}
lseek(fd,offs,SEEK_SET);
com_filesize=len;
@ -401,8 +403,10 @@ COM_OpenRead (const char *path, int offs, int len)
#ifdef WIN32
setmode(fd,O_BINARY);
#endif
return Qdopen(fd,"rbz");
return 0;
if (zip)
return Qdopen(fd,"rbz");
else
return Qdopen(fd,"rb");
}
int file_from_pak; // global indicating file came from pack file ZOID
@ -414,7 +418,7 @@ int file_from_pak; // global indicating file came from pack file ZOID
Sets com_filesize and one of handle or file
*/
int
COM_FOpenFile (char *filename, QFile **gzfile)
_COM_FOpenFile (char *filename, QFile **gzfile, char *foundname, int zip)
{
searchpath_t *search;
char netpath[MAX_OSPATH];
@ -460,8 +464,9 @@ COM_FOpenFile (char *filename, QFile **gzfile)
if (developer->int_val)
Sys_Printf ("PackFile: %s : %s\n",pak->filename, fn);
// open a new file on the pakfile
*gzfile=COM_OpenRead(pak->filename,pak->files[i].filepos,
pak->files[i].filelen);
strncpy(foundname, fn, MAX_OSPATH);
*gzfile=COM_OpenRead(pak->filename, pak->files[i].filepos,
pak->files[i].filelen, zip);
file_from_pak = 1;
return com_filesize;
}
@ -473,9 +478,11 @@ COM_FOpenFile (char *filename, QFile **gzfile)
snprintf(netpath, sizeof(netpath), "%s/%s",search->filename,
filename);
strncpy(foundname, filename, MAX_OSPATH);
findtime = Sys_FileTime (netpath);
if (findtime == -1) {
#ifdef HAS_ZLIB
strncpy(foundname, gzfilename, MAX_OSPATH);
snprintf(netpath, sizeof(netpath), "%s/%s",search->filename,
gzfilename);
findtime = Sys_FileTime (netpath);
@ -487,7 +494,7 @@ COM_FOpenFile (char *filename, QFile **gzfile)
if(developer->int_val)
Sys_Printf ("FindFile: %s\n",netpath);
*gzfile=COM_OpenRead(netpath,-1,-1);
*gzfile=COM_OpenRead(netpath, -1, -1, zip);
return com_filesize;
}
@ -500,6 +507,13 @@ COM_FOpenFile (char *filename, QFile **gzfile)
return -1;
}
int
COM_FOpenFile (char *filename, QFile **gzfile)
{
char foundname[MAX_OSPATH];
return _COM_FOpenFile (filename, gzfile, foundname, 1);
}
cache_user_t *loadcache;
byte *loadbuf;
int loadsize;

View file

@ -685,6 +685,11 @@ SV_BeginDownload_f
void SV_BeginDownload_f(void)
{
char *name;
QFile *file;
int size;
char realname[MAX_OSPATH];
int zip;
extern cvar_t *allow_download;
extern cvar_t *allow_download_skins;
extern cvar_t *allow_download_models;
@ -730,8 +735,12 @@ void SV_BeginDownload_f(void)
*p = tolower((int)*p);
}
zip = strchr(Info_ValueForKey (host_client->userinfo, "*cap"), 'z') != 0;
host_client->downloadsize = COM_FOpenFile (name, &host_client->download);
size = _COM_FOpenFile (name, &file, realname, zip);
host_client->download = file;
host_client->downloadsize = size;
host_client->downloadcount = 0;
if (!host_client->download
@ -751,6 +760,16 @@ void SV_BeginDownload_f(void)
return;
}
if (zip && strcmp (realname, name)) {
Sys_Printf ("download renamed to %s\n", realname);
ClientReliableWrite_Begin (host_client, svc_download,
strlen(realname)+5);
ClientReliableWrite_Short (host_client, -2);
ClientReliableWrite_Byte (host_client, 0);
ClientReliableWrite_String (host_client, realname);
ClientReliable_FinishWrite (host_client);
}
SV_NextDownload_f ();
Sys_Printf ("Downloading %s to %s\n", name, host_client->name);
}