예제 #1
0
/*
 * 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;
}
예제 #2
0
/*
===============
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: cl_parse.c 프로젝트: Slipyx/r1q2
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;
}
예제 #5
0
파일: cl_parse.c 프로젝트: Slipyx/r1q2
/*
===============
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;
	}
}
예제 #6
0
파일: cl_parse.c 프로젝트: Slipyx/r1q2
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 ();
	}
}
예제 #7
0
/*
=====================
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();
    }
}
예제 #8
0
/*
 * 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 ();
	}
}
예제 #9
0
/*
===============
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;
}
예제 #10
0
/*
=====================
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 ();
	}
}
예제 #11
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;
	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;
}