mirror of
https://git.code.sf.net/p/quake/newtree
synced 2025-02-16 16:41:30 +00:00
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:
parent
1a7f2af4ec
commit
1aa9084aa9
5 changed files with 83 additions and 34 deletions
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue