Exemple #1
0
static void Com_SetupDownload(const char *remote, const char *filename)
{
	dld.bWWWDl             = qtrue;
	dld.bWWWDlDisconnected = qtrue;

	// download format: @remotename@localname
	Q_strncpyz(dld.downloadList, va("@%s@%s", filename, filename), MAX_INFO_STRING);
	Q_strncpyz(dld.originalDownloadName, va("%s/%s", Cvar_VariableString("fs_game"), filename), sizeof(dld.originalDownloadName));
	Q_strncpyz(dld.downloadName, va("%s/%s", remote, filename), sizeof(dld.downloadName));
	Q_strncpyz(dld.downloadTempName, FS_BuildOSPath(Cvar_VariableString("fs_homepath"), Cvar_VariableString("fs_game"), va("%s.tmp", filename)), sizeof(dld.downloadTempName));

	if (!DL_BeginDownload(dld.downloadTempName, dld.downloadName))
	{
		Com_Error(ERR_DROP, "Could not download file: \"%s\"", dld.downloadName);
		dld.bWWWDlAborting = qtrue;
	}
}
Exemple #2
0
/*
=====================
CL_ParseDownload

A download message has been received from the server
=====================
*/
void CL_ParseDownload( msg_t *msg )
{
	int           size;
	unsigned char data[ MAX_MSGLEN ];
	int           block;

	if ( !*cls.downloadTempName )
	{
		Com_Printf("%s", _( "Server sending download, but no download was requested\n" ));
		CL_AddReliableCommand( "stopdl" );
		return;
	}

	// read the data
	block = MSG_ReadShort( msg );

	// TTimo - www dl
	// if we haven't acked the download redirect yet
	if ( block == -1 )
	{
		if ( !clc.bWWWDl )
		{
			// server is sending us a www download
			Q_strncpyz( cls.originalDownloadName, cls.downloadName, sizeof( cls.originalDownloadName ) );
			Q_strncpyz( cls.downloadName, MSG_ReadString( msg ), sizeof( cls.downloadName ) );
			clc.downloadSize = MSG_ReadLong( msg );
			clc.downloadFlags = MSG_ReadLong( msg );

			Cvar_SetValue( "cl_downloadSize", clc.downloadSize );
			Com_DPrintf( "Server redirected download: %s\n", cls.downloadName );
			clc.bWWWDl = qtrue; // activate wwwdl client loop
			CL_AddReliableCommand( "wwwdl ack" );

			// make sure the server is not trying to redirect us again on a bad checksum
			if ( strstr( clc.badChecksumList, va( "@%s", cls.originalDownloadName ) ) )
			{
				Com_Printf(_( "refusing redirect to %s by server (bad checksum)\n"), cls.downloadName );
				CL_AddReliableCommand( "wwwdl fail" );
				clc.bWWWDlAborting = qtrue;
				return;
			}

			// make downloadTempName an OS path
			Q_strncpyz( cls.downloadTempName, FS_BuildOSPath( Cvar_VariableString( "fs_homepath" ), cls.downloadTempName, "" ),
			            sizeof( cls.downloadTempName ) );
			cls.downloadTempName[ strlen( cls.downloadTempName ) - 1 ] = '\0';

			if ( !DL_BeginDownload( cls.downloadTempName, cls.downloadName, com_developer->integer ) )
			{
				// setting bWWWDl to false after sending the wwwdl fail doesn't work
				// not sure why, but I suspect we have to eat all remaining block -1 that the server has sent us
				// still leave a flag so that CL_WWWDownload is inactive
				// we count on server sending us a gamestate to start up clean again
				CL_AddReliableCommand( "wwwdl fail" );
				clc.bWWWDlAborting = qtrue;
				Com_Printf(_( "Failed to initialize download for '%s'\n"), cls.downloadName );
			}

			// Check for a disconnected download
			// we'll let the server disconnect us when it gets the bbl8r message
			if ( clc.downloadFlags & ( 1 << DL_FLAG_DISCON ) )
			{
				CL_AddReliableCommand( "wwwdl bbl8r" );
				cls.bWWWDlDisconnected = qtrue;
			}

			return;
		}
		else
		{
			// server keeps sending that message till we ack it, eat and ignore
			//MSG_ReadLong( msg );
			MSG_ReadString( msg );
			MSG_ReadLong( msg );
			MSG_ReadLong( msg );
			return;
		}
	}

	if ( !block )
	{
		// block zero is special, contains file size
		clc.downloadSize = MSG_ReadLong( msg );

		Cvar_SetValue( "cl_downloadSize", clc.downloadSize );

		if ( clc.downloadSize < 0 )
		{
			Com_Error( ERR_DROP, "%s", MSG_ReadString( msg ) );
		}
	}

	size = MSG_ReadShort( msg );

	if ( size < 0 || size > sizeof( data ) )
	{
		Com_Error( ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size );
	}

	MSG_ReadData( msg, data, size );

	if ( clc.downloadBlock != block )
	{
		Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", clc.downloadBlock, block );
		return;
	}

	// open the file if not opened yet
	if ( !clc.download )
	{
		clc.download = FS_SV_FOpenFileWrite( cls.downloadTempName );

		if ( !clc.download )
		{
			Com_Printf(_( "Could not create %s\n"), cls.downloadTempName );
			CL_AddReliableCommand( "stopdl" );
			CL_NextDownload();
			return;
		}
	}

	if ( size )
	{
		FS_Write( data, size, clc.download );
	}

	CL_AddReliableCommand( va( "nextdl %d", clc.downloadBlock ) );
	clc.downloadBlock++;

	clc.downloadCount += size;

	// So UI gets access to it
	Cvar_SetValue( "cl_downloadCount", clc.downloadCount );

	if ( !size )
	{
		// A zero length block means EOF
		if ( clc.download )
		{
			FS_FCloseFile( clc.download );
			clc.download = 0;

			// rename the file
			FS_SV_Rename( cls.downloadTempName, cls.downloadName );
		}

		*cls.downloadTempName = *cls.downloadName = 0;
		Cvar_Set( "cl_downloadName", "" );

		// send intentions now
		// We need this because without it, we would hold the last nextdl and then start
		// loading right away.  If we take a while to load, the server is happily trying
		// to send us that last block over and over.
		// Write it twice to help make sure we acknowledge the download
		CL_WritePacket();
		CL_WritePacket();

		// get another file if needed
		CL_NextDownload();
	}
}
Exemple #3
0
qboolean CL_InitUpdateDownloads(void)
{
#ifdef FEATURE_AUTOUPDATE
	if (autoupdate.updateStarted && NET_CompareAdr(autoupdate.autoupdateServer, clc.serverAddress))
	{
		if (strlen(com_updatefiles->string) > 4)
		{
			char *updateFile;
			char updateFilesRemaining[MAX_TOKEN_CHARS] = "";

			clc.bWWWDl             = qtrue;
			cls.bWWWDlDisconnected = qtrue;

			updateFile = strtok(com_updatefiles->string, ";");

			if (updateFile == NULL)
			{
				Com_Error(ERR_AUTOUPDATE, "Could not parse update string.");
			}
			else
			{
				// download format: @remotename@localname
				Q_strncpyz(clc.downloadList, va("@%s@%s", updateFile, updateFile), MAX_INFO_STRING);
				Q_strncpyz(cls.originalDownloadName, updateFile, sizeof(cls.originalDownloadName));
				Q_strncpyz(cls.downloadName, va("%s/%s", UPDATE_SERVER_NAME, updateFile), sizeof(cls.downloadName));
				Q_strncpyz(cls.downloadTempName,
				           FS_BuildOSPath(Cvar_VariableString("fs_homepath"), AUTOUPDATE_DIR, va("%s.tmp", cls.originalDownloadName)),
				           sizeof(cls.downloadTempName));
				// TODO: add file size, so UI can show progress bar
				//Cvar_SetValue("cl_downloadSize", clc.downloadSize);

				if (!DL_BeginDownload(cls.downloadTempName, cls.downloadName))
				{
					Com_Error(ERR_AUTOUPDATE, "Could not download an update file: \"%s\"", cls.downloadName);
					clc.bWWWDlAborting = qtrue;
				}

				while (1)
				{
					updateFile = strtok(NULL, ";");

					if (updateFile == NULL)
					{
						break;
					}

					Q_strcat(updateFilesRemaining, sizeof(updateFilesRemaining), va("%s;", updateFile));
				}

				if (strlen(updateFilesRemaining) > 4)
				{
					Cvar_Set("com_updatefiles", updateFilesRemaining);
				}
				else
				{
					Cvar_Set("com_updatefiles", "");
				}
			}
		}
		return qtrue;
	}
#endif // FEATURE_AUTOUPDATE

	return qfalse;
}