/* * Returns true if the file exists, otherwise it attempts * to start a download from the server. */ qboolean CL_CheckOrDownloadFile (char *filename) { FILE *fp; char name[MAX_OSPATH]; char *ptr; if (strstr (filename, "..")) { Com_Printf ("Refusing to download a path with ..\n"); return true; } /* fix backslashes - this is mostly für UNIX comaptiblity */ while ((ptr=strchr(filename,'\\'))) { *ptr = '/'; } if (FS_LoadFile (filename, NULL) != -1) { /* it exists, no need to download */ return true; } strcpy (cls.downloadname, filename); /* 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"); /* check to see if we already have a tmp for this file, if so, try to resume and open the file if not opened yet */ CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); fp = fopen (name, "r+b"); if (fp) { /* it exists */ int len; fseek(fp, 0, SEEK_END); len = ftell(fp); cls.download = fp; /* give the server an offset to start the download */ Com_Printf ("Resuming %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s %i", cls.downloadname, len)); } else { Com_Printf ("Downloading %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); } cls.downloadnumber++; return false; }
/* =============== CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ qboolean CL_CheckOrDownloadFile(char * filename) { FILE * fp; char name[MAX_OSPATH]; if (strstr(filename, "..")) { Com_Printf("Refusing to download a path with ..\n"); return true; } if (FS_LoadFile(filename, NULL) != -1) { // it exists, no need to download return true; } strcpy(cls.downloadname, filename); // 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"); //ZOID // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); // FS_CreatePath (name); fp = fopen(name, "r+b"); if (fp) { // it exists int len; fseek(fp, 0, SEEK_END); len = ftell(fp); cls.download = fp; // give the server an offset to start the download Com_Printf("Resuming %s\n", cls.downloadname); MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteString(&cls.netchan.message, va("download %s %i", cls.downloadname, len)); } else { Com_Printf("Downloading %s\n", cls.downloadname); MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteString(&cls.netchan.message, va("download %s", cls.downloadname)); } cls.downloadnumber++; return false; }
static void CL_FinishDownload (void) { char oldn[MAX_OSPATH], newn[MAX_OSPATH]; fclose (cls.download); // rename the temp file to it's final name CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); if (!FS_RenameFile(oldn, newn)) Com_Printf ("failed to rename.\n"); cls.failed_download = false; cls.downloadname[0] = 0; cls.downloadposition = 0; cls.download = NULL; cls.downloadpercent = 0; }
void CL_FinishDownload (void) { #ifdef _DEBUG clientinfo_t *ci; #endif int r; char oldn[MAX_OSPATH]; char newn[MAX_OSPATH]; fclose (cls.download); FS_FlushCache(); // rename the temp file to it's final name CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); r = rename (oldn, newn); if (r) Com_Printf ("failed to rename.\n", LOG_CLIENT); #ifdef _DEBUG if (cls.serverProtocol == PROTOCOL_R1Q2 && (strstr(newn, "players"))) { for (r = 0; r < cl.maxclients; r++) { ci = &cl.clientinfo[r]; if (ci->deferred) CL_ParseClientinfo (r); } } #endif cls.failed_download = false; cls.downloadpending = false; cls.downloadname[0] = 0; cls.downloadposition = 0; cls.download = NULL; cls.downloadpercent = 0; }
/* =============== CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ qboolean CL_CheckOrDownloadFile (const char *filename) { FILE *fp; int length; char *p; char name[MAX_OSPATH]; static char lastfilename[MAX_OSPATH] = {0}; //r1: don't attempt same file many times if (!strcmp (filename, lastfilename)) return true; strcpy (lastfilename, filename); if (strstr (filename, "..")) { Com_Printf ("Refusing to check a path with .. (%s)\n", LOG_CLIENT, filename); return true; } if (strchr (filename, ' ')) { Com_Printf ("Refusing to check a path containing spaces (%s)\n", LOG_CLIENT, filename); return true; } if (strchr (filename, ':')) { Com_Printf ("Refusing to check a path containing a colon (%s)\n", LOG_CLIENT, filename); return true; } if (filename[0] == '/') { Com_Printf ("Refusing to check a path starting with / (%s)\n", LOG_CLIENT, filename); return true; } if (FS_LoadFile (filename, NULL) != -1) { // it exists, no need to download return true; } #ifdef USE_CURL if (CL_QueueHTTPDownload (filename)) { //we return true so that the precache check keeps feeding us more files. //since we have multiple HTTP connections we want to minimize latency //and be constantly sending requests, not one at a time. return true; } else #endif { strcpy (cls.downloadname, filename); //r1: fix \ to / p = cls.downloadname; while ((p = strchr(p, '\\')) != NULL) p[0] = '/'; length = (int)strlen(cls.downloadname); //normalize path p = cls.downloadname; while ((p = strstr (p, "./")) != NULL) { memmove (p, p+2, length - (p - cls.downloadname) - 1); length -= 2; } //r1: verify we are giving the server a legal path if (cls.downloadname[length-1] == '/') { Com_Printf ("Refusing to download bad path (%s)\n", LOG_CLIENT, filename); return true; } // 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"); //ZOID // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); // FS_CreatePath (name); fp = fopen (name, "r+b"); if (fp) { // it exists int len; fseek(fp, 0, SEEK_END); len = ftell(fp); cls.download = fp; // give the server an offset to start the download Com_Printf ("Resuming %s\n", LOG_CLIENT, cls.downloadname); MSG_WriteByte (clc_stringcmd); if (cls.serverProtocol == PROTOCOL_R1Q2) MSG_WriteString (va("download \"%s\" %i udp-zlib", cls.downloadname, len)); else MSG_WriteString (va("download \"%s\" %i", cls.downloadname, len)); } else { Com_Printf ("Downloading %s\n", LOG_CLIENT, cls.downloadname); MSG_WriteByte (clc_stringcmd); if (cls.serverProtocol == PROTOCOL_R1Q2) MSG_WriteString (va("download \"%s\" 0 udp-zlib", cls.downloadname)); else MSG_WriteString (va("download \"%s\"", cls.downloadname)); } MSG_EndWriting (&cls.netchan.message); send_packet_now = true; cls.downloadpending = true; return false; } }
void CL_ParseDownload (qboolean dataIsCompressed) { int size, percent; char name[MAX_OSPATH]; // read the data size = MSG_ReadShort (&net_message); percent = MSG_ReadByte (&net_message); if (size < 0) { if (size == -1) Com_Printf ("Server does not have this file.\n", LOG_CLIENT); else Com_Printf ("Bad download data from server.\n", LOG_CLIENT); //r1: nuke the temp filename cls.downloadtempname[0] = 0; cls.downloadname[0] = 0; cls.failed_download = true; if (cls.download) { // if here, we tried to resume a file but the server said no fclose (cls.download); cls.download = NULL; } cls.downloadpending = false; CL_RequestNextDownload (); return; } // open the file if not opened yet if (!cls.download) { if (!cls.downloadtempname[0]) { Com_Printf ("Received download packet without request. Ignored.\n", LOG_CLIENT); net_message.readcount += size; return; } CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath (name); cls.download = fopen (name, "wb"); if (!cls.download) { net_message.readcount += size; Com_Printf ("Failed to open %s\n", LOG_CLIENT, cls.downloadtempname); cls.downloadpending = false; CL_RequestNextDownload (); return; } } //r1: downloading something, drop to console to show status bar SCR_EndLoadingPlaque(); //r1: if we're stuck with udp, may as well make best use of the bandwidth... if (dataIsCompressed) { #ifndef NO_ZLIB uint16 uncompressedLen; byte uncompressed[0xFFFF]; uncompressedLen = (uint16)MSG_ReadShort (&net_message); if (!uncompressedLen) Com_Error (ERR_DROP, "uncompressedLen == 0"); ZLibDecompress (net_message_buffer + net_message.readcount, size, uncompressed, uncompressedLen, -15); fwrite (uncompressed, 1, uncompressedLen, cls.download); Com_DPrintf ("svc_zdownload(%s): %d -> %d\n", cls.downloadname, size, uncompressedLen); #else Com_Error (ERR_DROP, "Received a unrequested compressed download"); #endif } else { fwrite (net_message_buffer + net_message.readcount, 1, size, cls.download); } net_message.readcount += size; if (percent != 100) { cls.downloadpercent = percent; MSG_WriteByte (clc_stringcmd); MSG_Print ("nextdl"); MSG_EndWriting (&cls.netchan.message); send_packet_now = true; } else { CL_FinishDownload (); // get another file if needed CL_RequestNextDownload (); } }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload(void) { int size, percent; char name[MAX_OSPATH]; int r; // read the data size = MSG_ReadShort(&net_message); percent = MSG_ReadByte(&net_message); if (size == -1) { Com_Printf("Server does not have this file.\n"); if (cls.download) { // if here, we tried to resume a file but the server said no fclose(cls.download); cls.download = NULL; } CL_RequestNextDownload(); return; } // open the file if not opened yet if (!cls.download) { CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath(name); cls.download = fopen(name, "wb"); if (!cls.download) { net_message.readcount += size; Com_Printf("Failed to open %s\n", cls.downloadtempname); CL_RequestNextDownload(); return; } } fwrite(net_message.data + net_message.readcount, 1, size, cls.download); net_message.readcount += size; if (percent != 100) { // request next block // change display routines by zoid #if 0 Com_Printf ("."); if (10*(percent/10) != cls.downloadpercent) { cls.downloadpercent = 10*(percent/10); Com_Printf ("%i%%", cls.downloadpercent); } #endif cls.downloadpercent = percent; MSG_WriteByte(&cls.netchan.message, clc_stringcmd); SZ_Print(&cls.netchan.message, "nextdl"); } else { char oldn[MAX_OSPATH]; char newn[MAX_OSPATH]; // Com_Printf ("100%%\n"); fclose(cls.download); // rename the temp file to it's final name CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); r = rename(oldn, newn); if (r) Com_Printf("failed to rename.\n"); cls.download = NULL; cls.downloadpercent = 0; // get another file if needed CL_RequestNextDownload(); } }
/* * A download message has been received from the server */ void CL_ParseDownload (void) { int size, percent; char name[MAX_OSPATH]; int r; /* read the data */ size = MSG_ReadShort (&net_message); percent = MSG_ReadByte (&net_message); if (size == -1) { Com_Printf ("Server does not have this file.\n"); if (cls.download) { /* if here, we tried to resume a file but the server said no */ fclose (cls.download); cls.download = NULL; } CL_RequestNextDownload (); return; } /* open the file if not opened yet */ if (!cls.download) { CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath (name); cls.download = fopen (name, "wb"); if (!cls.download) { net_message.readcount += size; Com_Printf ("Failed to open %s\n", cls.downloadtempname); CL_RequestNextDownload (); return; } } fwrite (net_message.data + net_message.readcount, 1, size, cls.download); net_message.readcount += size; if (percent != 100) { /* request next block */ cls.downloadpercent = percent; MSG_WriteByte (&cls.netchan.message, clc_stringcmd); SZ_Print (&cls.netchan.message, "nextdl"); } else { char oldn[MAX_OSPATH]; char newn[MAX_OSPATH]; fclose (cls.download); /* rename the temp file to it's final name */ CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); r = rename (oldn, newn); if (r) Com_Printf ("failed to rename.\n"); cls.download = NULL; cls.downloadpercent = 0; /* get another file if needed */ CL_RequestNextDownload (); } }
/* =============== CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ qboolean CL_CheckOrDownloadFile (char *filename) { FILE *fp; char name[MAX_OSPATH]; int32_t len; // Knightmare added char s[128]; //int32_t i; if (strstr (filename, "..")) { Com_Printf ("Refusing to download a path with ..\n"); return true; } if (FS_LoadFile (filename, NULL) != -1) { // it exists, no need to download return true; } // don't try again to download a file that just failed if (CL_CheckDownloadFailed(filename)) return true; // don't download a .tga texture which already has a .jpg counterpart len = strlen(filename); strcpy(s,filename); if (strstr(s, "textures/") && !strcmp(s+len-4, ".tga")) // look if we have a .tga texture { s[len-3]='j'; s[len-2]='p'; s[len-1]='g'; // replace extension if (FS_LoadFile (s, NULL) != -1) // check for .jpg counterpart return true; } strcpy (cls.downloadname, filename); // 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"); //ZOID // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); // FS_CreatePath (name); fp = fopen (name, "r+b"); if (fp) { // it exists int32_t len; fseek(fp, 0, SEEK_END); len = ftell(fp); cls.download = fp; // give the server an offset to start the download Com_Printf ("Resuming %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s %i", cls.downloadname, len)); } else { Com_Printf ("Downloading %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); } cls.downloadnumber++; return false; }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload (sizebuf_t *msg, qboolean dataIsCompressed) { int size, percent; char name[MAX_OSPATH]; // int r; // read the data size = MSG_ReadShort (msg); percent = MSG_ReadByte (msg); if (size < 0) { if (size == -1) Com_Printf ("Server does not have this file.\n"); else Com_Printf ("Bad download data from server.\n"); cls.downloadtempname[0] = 0; cls.downloadname[0] = 0; cls.failed_download = true; if (cls.download) { // if here, we tried to resume a file but the server said no fclose (cls.download); cls.download = NULL; } CL_RequestNextDownload (); return; } // open the file if not opened yet if (!cls.download) { if (!cls.downloadtempname[0]) { Com_Printf ("Received download packet without request. Ignored.\n"); msg->readcount += size; return; } CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath (name); cls.download = fopen (name, "wb"); if (!cls.download) { msg->readcount += size; Com_Printf ("Failed to open %s\n", cls.downloadtempname); CL_RequestNextDownload (); return; } } if (dataIsCompressed) { uint16 uncompressedLen; byte uncompressed[0xFFFF]; uncompressedLen = MSG_ReadShort (msg); if (!uncompressedLen) Com_Error (ERR_DROP, "uncompressedLen == 0"); ZLibDecompress (msg->data + msg->readcount, size, uncompressed, uncompressedLen, -15); fwrite (uncompressed, 1, uncompressedLen, cls.download); Com_DPrintf ("svc_zdownload(%s): %d -> %d\n", cls.downloadname, size, uncompressedLen); } else { fwrite (msg->data + msg->readcount, 1, size, cls.download); } //fwrite (net_message.data + net_message.readcount, 1, size, cls.download); msg->readcount += size; if (percent != 100) { // request next block // change display routines by zoid cls.downloadpercent = percent; MSG_WriteByte (&cls.netchan.message, clc_stringcmd); SZ_Print (&cls.netchan.message, "nextdl"); } else { CL_FinishDownload(); // get another file if needed CL_RequestNextDownload (); } }
/* =============== CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ qboolean CL_CheckOrDownloadFile (const char *filename) { FILE *fp; char name[MAX_OSPATH]; static char lastfilename[MAX_OSPATH] = "\0"; Q_strncpyz(name, filename, sizeof(name)); COM_FixPath(name); filename = name; //r1: don't attempt same file many times if (!strcmp (filename, lastfilename)) return true; strcpy (lastfilename, filename); if (strstr (filename, "..")) { Com_Printf ("Refusing to download a path with .. (%s)\n", filename); return true; } if (strchr (filename, ' ')) { Com_Printf ("Refusing to check a path containing spaces (%s)\n", filename); return true; } if (strchr (filename, ':')) { Com_Printf ("Refusing to check a path containing a colon (%s)\n", filename); return true; } if (FS_LoadFile (filename, NULL) != -1) { // it exists, no need to download return true; } #ifdef USE_CURL if (CL_QueueHTTPDownload (filename)) { //we return true so that the precache check keeps feeding us more files. //since we have multiple HTTP connections we want to minimize latency //and be constantly sending requests, not one at a time. return true; } #endif strcpy (cls.downloadname, filename); // 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"); //ZOID // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); // FS_CreatePath (name); fp = fopen (name, "r+b"); if (fp) { // it exists int len; fseek(fp, 0, SEEK_END); len = ftell(fp); cls.download = fp; // give the server an offset to start the download Com_Printf ("Resuming %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); if (cls.serverProtocol == PROTOCOL_VERSION_R1Q2) MSG_WriteString (&cls.netchan.message, va("download \"%s\" %i udp-zlib", cls.downloadname, len)); else MSG_WriteString (&cls.netchan.message, va("download \"%s\" %i", cls.downloadname, len)); } else { Com_Printf ("Downloading %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); if (cls.serverProtocol == PROTOCOL_VERSION_R1Q2) MSG_WriteString (&cls.netchan.message, va("download \"%s\" 0 udp-zlib", cls.downloadname)); else MSG_WriteString (&cls.netchan.message, va("download \"%s\"", cls.downloadname)); } //cls.downloadnumber++; return false; }