Ejemplo n.º 1
0
/*
==================
SV_WriteBans_f

Save bans to file.
==================
*/
static void SV_WriteBans(void)
{
	int index;
	fileHandle_t writeto;
	char filepath[MAX_QPATH];
	
	if(!sv_banFile->string || !*sv_banFile->string)
		return;
	
	Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string);

	if((writeto = FS_SV_FOpenFileWrite(filepath)))
	{
		char writebuf[128];
		serverBan_t *curban;
		
		for(index = 0; index < serverBansCount; index++)
		{
			curban = &serverBans[index];
			
			Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d\n",
				    curban->isexception, NET_AdrToString(curban->ip), curban->subnet);
			FS_Write(writebuf, strlen(writebuf), writeto);
		}

		FS_FCloseFile(writeto);
	}
}
Ejemplo n.º 2
0
/*
==============
Sys_ErrorDialog

Display an error message
==============
*/
void Sys_ErrorDialog( const char *error )
{
	char buffer[ 1024 ];
	unsigned int size;
	fileHandle_t f;
	const char *fileName = "crashlog.txt";

	// Shut down now so that the curses console doesn't clear the screen when it's really shut down
	CON_Shutdown( );

	Sys_Print( va( "%s\n", error ) );

	// Write console log to file and to stderr
	f = FS_SV_FOpenFileWrite( fileName );
	if( !f )
	{
		Com_Printf( "ERROR: couldn't open %s\n", fileName );
		return;
	}

	while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 )
	{
		FS_Write( buffer, size, f );
		fputs( buffer, stderr );
	}

	FS_FCloseFile( f );
}
Ejemplo n.º 3
0
/*
==================
SV_WriteBans_f

Save bans to file.
==================
 */
static void SV_WriteBans(void) {
    int index;
    fileHandle_t writeto;
    char *curpos, filepath[MAX_QPATH];

    if (!sv_banFile->string || !*sv_banFile->string)
        return;

    if (!(curpos = Cvar_VariableString("fs_game")) || !*curpos)
        curpos = BASEGAME;

    Com_sprintf(filepath, sizeof (filepath), "%s/%s", curpos, sv_banFile->string);

    if ((writeto = FS_SV_FOpenFileWrite(filepath))) {
        char writebuf[128];
        serverBan_t *curban;

        for (index = 0; index < serverBansCount; index++) {
            curban = &serverBans[index];

            Com_sprintf(writebuf, sizeof (writebuf), "%d %s %d\n",
                    curban->isexception, NET_AdrToString(curban->ip), curban->subnet);
            FS_Write(writebuf, strlen(writebuf), writeto);
        }

        FS_FCloseFile(writeto);
    }
}
Ejemplo n.º 4
0
void HStorage_WriteDataToFile(varStorage_t* vobj, const char* filename){

    fileHandle_t file;
    char infostring[8192], buf[128];
    int i;
    char name[MAX_VARNAME];
    char *string;
    int count;
    vsMemObj_t* obj;
    vsValue_t value;
    varType_t type;
    mvabuf;

    obj = vobj->memObj;

    file = FS_SV_FOpenFileWrite(va("%s.tmp", filename));
    if(!file){
        Com_PrintError("HStorage_WriteDataToFile: Can not open %s for writing\n", filename);
        return;
    }

    HStorage_IterInit( obj );

    while(HStorage_IterHasNext( obj ))
    {
            count = HStorage_IterGetNextInfo( obj, name, &type );

            if(count == 0)
            {
                continue;
            }

            *infostring = 0;
            BigInfo_SetValueForKey(infostring, "name", name);
            BigInfo_SetValueForKey(infostring, "type", HStorage_EnumToVarType(type));
            BigInfo_SetValueForKey(infostring, "count", va("%d", count));

            for(i = 0; i < count; i++)
            {
                if(HStorage_GetDataInternal(obj, &value) == 0)
                {
                    break;
                }

                if(type == VSVAR_STRING)
                {
                    string = HStorage_ValueToString(type, &value, buf, sizeof(buf));
                    BigInfo_SetEncodedValueForKey(infostring, va("v%d", i), string, strlen(string));
                }else{
                    BigInfo_SetValueForKey(infostring, va("v%d", i), HStorage_ValueToString(type, &value, buf, sizeof(buf)));
                }
            }

            Q_strcat(infostring, sizeof(infostring), "\\\n");
            FS_Write(infostring, strlen(infostring), file);
    }
    FS_FCloseFile(file);
    FS_SV_HomeCopyFile(va("%s.tmp", filename) , (char*)filename);
}
Ejemplo n.º 5
0
static size_t Curl_WriteCallback_f(void *ptr, size_t size, size_t nmemb, void *stream) {
	if (!f) {
		char dir[MAX_OSPATH];
		char dirt[MAX_OSPATH];
		char *c;
		// make sure Content-Type is either "application/octet-stream" or "application/zip".
		if (curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &c) != CURLE_OK
				|| !c
				|| (Q_stricmp(c, "application/octet-stream")
					&& Q_stricmp(c, "application/zip"))) {
			Q_strncpyz(dl_error, "No pk3 returned - requested map is probably unknown.", sizeof(dl_error));
			return 0;
		}
		// make sure the path doesn't have directory information.
		for (c=path; *c; c++) {
			if (*c == '\\' || *c == '/' || *c == ':') {
				Com_sprintf(dl_error, sizeof(dl_error), "Destination filename \"%s\" is not valid.", path);
				return 0;
			}
		}

		// make sure the file has an appropriate extension.
		c = path +strlen(path) -4;
		if (c <= path || strcmp(c, ".pk3")) {
			Com_sprintf(dl_error, sizeof(dl_error), "Returned file \"%s\" has wrong extension.", path);
			return 0;
		}

		// make out the directory in which to place the file
		Q_strncpyz(dir, (dl_usebaseq3->integer)?"baseq3":FS_GetCurrentGameDir(), sizeof(dir));
		if (strlen(path) +strlen(dir) +1 >= sizeof(path)) {
			Com_sprintf(dl_error, sizeof(dl_error), "Returned filename is too large.");
			return 0;
		}

		Com_sprintf(dirt, sizeof(dirt), "%s/%s", dir, path);
		strcpy(path,dirt);

		// in case of a name collision, just fail - leave it to the user to sort out.
		if (FS_FileExists(path)) {
			Com_sprintf(dl_error, sizeof(dl_error), "Failed to download \"%s\", a pk3 by that name exists locally.", path);
			return 0;
		}

		// change the extension to .tmp - it will be changed back once the download is complete.
		c = path +strlen(path) -4;
		strcpy(c, ".tmp"); 

		// FS should write the file in the appropriate gamedir and catch unsanitary paths.
		f = FS_SV_FOpenFileWrite(path);
		if (!f) {
			Com_sprintf(dl_error, sizeof(dl_error), "Failed to open \"%s\" for writing.\n", path);
			return 0;
		}
		Com_Printf("Writing to: %s\n", path);
	}
	return FS_Write(ptr, size*nmemb, f);
}
Ejemplo n.º 6
0
/*
====================
LAN_SaveServersToCache
====================
*/
void LAN_SaveServersToCache( void ) {
	int size;
	fileHandle_t fileOut = FS_SV_FOpenFileWrite("servercache.dat");
	FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
	FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
	size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers);
	FS_Write(&size, sizeof(int), fileOut);
	FS_Write(&cls.globalServers, sizeof(cls.globalServers), fileOut);
	FS_Write(&cls.favoriteServers, sizeof(cls.favoriteServers), fileOut);
	FS_FCloseFile(fileOut);
}
Ejemplo n.º 7
0
/*
===============
inspired from http://www.w3.org/Library/Examples/LoadToFile.c
setup the download, return once we have a connection
===============
*/
int DL_BeginDownload( const char *localName, const char *remoteName, int debug )
{
	char referer[ MAX_STRING_CHARS + URI_SCHEME_LENGTH ];

	if ( dl_request )
	{
		curl_multi_remove_handle( dl_multi, dl_request );
		curl_easy_cleanup( dl_request );
		dl_request = NULL;
	}

	if ( dl_file )
	{
		FS_FCloseFile( dl_file );
		dl_file = 0;
	}

	if ( !localName || !remoteName )
	{
		Com_DPrintf( "Empty download URL or empty local file name\n" );
		return 0;
	}

	dl_file = FS_SV_FOpenFileWrite( localName );

	if ( !dl_file )
	{
		Com_Printf( "ERROR: DL_BeginDownload unable to open '%s' for writing\n", localName );
		return 0;
	}

	DL_InitDownload();

	strcpy( referer, URI_SCHEME );
	Q_strncpyz( referer + URI_SCHEME_LENGTH, Cvar_VariableString( "cl_currentServerIP" ), MAX_STRING_CHARS );

	dl_request = curl_easy_init();
	curl_easy_setopt( dl_request, CURLOPT_USERAGENT, va( "%s %s", PRODUCT_NAME "/" PRODUCT_VERSION, curl_version() ) );
	curl_easy_setopt( dl_request, CURLOPT_REFERER, referer );
	curl_easy_setopt( dl_request, CURLOPT_URL, remoteName );
	curl_easy_setopt( dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile );
	curl_easy_setopt( dl_request, CURLOPT_WRITEDATA, ( void * )( intptr_t ) dl_file );
	curl_easy_setopt( dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress );
	curl_easy_setopt( dl_request, CURLOPT_NOPROGRESS, 0 );
	curl_easy_setopt( dl_request, CURLOPT_FAILONERROR, 1 );

	curl_multi_add_handle( dl_multi, dl_request );

	Cvar_Set( "cl_downloadName", remoteName );

	return 1;
}
    void SaveHistory() {
        fileHandle_t f = FS_SV_FOpenFileWrite(HISTORY_FILE);

        if (!f) {
            Com_Printf("Couldn't write %s.\n", HISTORY_FILE);
            return;
        }

        for (unsigned i = std::max(0L, ((long)lines.size()) - SAVED_HISTORY_LINES); i < lines.size(); i++) {
            FS_Write(lines[i].data(), lines[i].size(), f);
            FS_Write("\n", 1, f);
        }

        FS_FCloseFile(f);
    }
Ejemplo n.º 9
0
/*
====================
LAN_SaveServersToCache
====================
*/
void LAN_SaveServersToCache( ) {
#ifndef _XBOX
	int size;
	fileHandle_t fileOut = FS_SV_FOpenFileWrite("servercache.dat");
	FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
	FS_Write(&cls.nummplayerservers, sizeof(int), fileOut);
	FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
	size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers) + sizeof(cls.mplayerServers);
	FS_Write(&size, sizeof(int), fileOut);
	FS_Write(&cls.globalServers, sizeof(cls.globalServers), fileOut);
	FS_Write(&cls.mplayerServers, sizeof(cls.mplayerServers), fileOut);
	FS_Write(&cls.favoriteServers, sizeof(cls.favoriteServers), fileOut);
	FS_FCloseFile(fileOut);
#endif
}
Ejemplo n.º 10
0
void SV_WriteBanlist(){

    banList_t *this;
    time_t aclock;
    time(&aclock);
    fileHandle_t file;
    char infostring[1024];
    int i;

    file = FS_SV_FOpenFileWrite(va("%s.tmp", banlistfile->string));
    if(!file){
        Com_PrintError("SV_WriteBanlist: Can not open %s for writing\n",banlistfile->string);
        return;
    }

    this = banlist;
    if(!this)
        return;

    for(i = 0 ; i < current_banindex; this++, i++){

        if(this->expire == (time_t)-1 || this->expire > aclock){

            *infostring = 0;
            if(this->playeruid > 0){
                Info_SetValueForKey(infostring, "uid", va("%i", this->playeruid));
            }else if(this->pbguid[7]){
                Info_SetValueForKey(infostring, "guid", this->pbguid);
            }else{
                continue;
            }
            Info_SetValueForKey(infostring, "nick", this->playername);
            Info_SetValueForKey(infostring, "rsn", this->reason);
            Info_SetValueForKey(infostring, "exp", va("%i", this->expire));
            Info_SetValueForKey(infostring, "auid", va("%i", this->adminuid));
            Q_strcat(infostring, sizeof(infostring), "\\\n");
            FS_Write(infostring,strlen(infostring),file);
        }
    }
    FS_FCloseFile(file);
    FS_SV_HomeCopyFile(va("%s.tmp", banlistfile->string) ,banlistfile->string);
//    FS_SV_Rename(va("%s.tmp", banlist->string),banlist->string);
}
Ejemplo n.º 11
0
/*
=================
CL_CloseJoystickRemap

Write out "<event> <key>" lines
=================
*/
void CL_CloseJoystickRemap( int localPlayerNum ) {
	fileHandle_t	f;
	char			filename[MAX_QPATH];
	int				i;
	joyDevice_t *device;

	if ( playerJoyRemapIndex[ localPlayerNum ] == -1 ) {
		return;
	}

	device = &joyDevice[ playerJoyRemapIndex[ localPlayerNum ] ];
	device->references--;

	playerJoyRemapIndex[ localPlayerNum ] = -1;

	if ( !device->modified ) {
		return;
	}
	device->modified = qfalse;

	Com_sprintf( filename, sizeof ( filename ), "joy-%s-%s.txt", JOY_PLATFORM, device->ident );

	f = FS_SV_FOpenFileWrite( filename );
	if ( !f ) {
		Com_Printf ("Couldn't write %s.\n", filename );
		return;
	}

	FS_Printf (f, "// Joystick remap created using " PRODUCT_NAME " on " JOY_PLATFORM " for %s\n", device->name);

	for ( i = 0 ; i < MAX_JOY_REMAPS ; i++ ) {
		if ( device->remap[i].event.type == JOYEVENT_NONE ) {
			continue;
		}

		FS_Printf (f, "%s %s\n", CL_JoyEventToString( &device->remap[i].event ),
								Key_KeynumToString( device->remap[i].keynum ) );
	}

	FS_FCloseFile( f );
}
Ejemplo n.º 12
0
/*
====================
LAN_SaveServersToCache
====================
*/
void LAN_SaveServersToCache() {
	int size;
	fileHandle_t fileOut;
#ifdef __MACOS__    //DAJ MacOS file typing
	{
		extern _MSL_IMP_EXP_C long _fcreator, _ftype;
		_ftype = 'WlfB';
		_fcreator = 'WlfM';
	}
#endif
	fileOut = FS_SV_FOpenFileWrite( "servercache.dat" );
	FS_Write( &cls.numglobalservers, sizeof( int ), fileOut );
	FS_Write( &cls.nummplayerservers, sizeof( int ), fileOut );
	FS_Write( &cls.numfavoriteservers, sizeof( int ), fileOut );
	size = sizeof( cls.globalServers ) + sizeof( cls.favoriteServers ) + sizeof( cls.mplayerServers );
	FS_Write( &size, sizeof( int ), fileOut );
	FS_Write( &cls.globalServers, sizeof( cls.globalServers ), fileOut );
	FS_Write( &cls.mplayerServers, sizeof( cls.mplayerServers ), fileOut );
	FS_Write( &cls.favoriteServers, sizeof( cls.favoriteServers ), fileOut );
	FS_FCloseFile( fileOut );
}
Ejemplo n.º 13
0
/*
==================
CL_SystemInfoChanged

The systeminfo configstring has been changed, so parse
new information out of it.  This will happen at every
gamestate, and possibly during gameplay.
==================
*/
void CL_SystemInfoChanged( void ) {
	char			*systemInfo;
	const char		*s, *t;
	char			key[BIG_INFO_KEY];
	char			value[BIG_INFO_VALUE];
	qboolean		gameSet;

	systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ];
	// NOTE TTimo:
	// when the serverId changes, any further messages we send to the server will use this new serverId
	// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475
	// in some cases, outdated cp commands might get sent with this news serverId
	cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );

#ifdef USE_VOIP
	s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
	clc.voipEnabled = !Q_stricmp(s, "opus");
#endif

	// don't set any vars when playing a demo
	if ( clc.demoplaying ) {
		return;
	}

	s = Info_ValueForKey( systemInfo, "sv_cheats" );
	cl_connectedToCheatServer = atoi( s );
	if ( !cl_connectedToCheatServer ) {
		Cvar_SetCheatState();
	}

	// check pure server string
	s = Info_ValueForKey( systemInfo, "sv_paks" );
	t = Info_ValueForKey( systemInfo, "sv_pakNames" );
	FS_PureServerSetLoadedPaks( s, t );

	s = Info_ValueForKey( systemInfo, "sv_referencedPaks" );
	t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" );
	FS_PureServerSetReferencedPaks( s, t );

	gameSet = qfalse;
	// scan through all the variables in the systeminfo and locally set cvars to match
	s = systemInfo;
	while ( s ) {
		Info_NextPair( &s, key, value );
		if ( !key[0] ) {
			break;
		}
		
		// ehw!
		if (!Q_stricmp(key, "fs_game"))
		{
			char filename[MAX_QPATH];
			char *title;

			if ( gameSet )
				continue;

			if(FS_CheckDirTraversal(value))
			{
				Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value);
				continue;
			}

			// create game title file if does not exist
			title = Info_ValueForKey( systemInfo, "sv_gameTitle" );
			Com_sprintf( filename, sizeof ( filename ), "%s/description.txt", value );
			if ( ( cl_allowDownload->integer & DLF_ENABLE ) && *title && !FS_SV_RW_FileExists( filename ) ) {
				fileHandle_t f = FS_SV_FOpenFileWrite( filename );
				FS_Write( s, strlen( title ), f );
				FS_FCloseFile( f );
			}

			gameSet = qtrue;
		}

		Cvar_Server_Set(key, value);
	}
	// game folder must be set
	if ( !gameSet ) {
		Com_Error( ERR_DROP, "fs_game not set on server" );
	}
}
Ejemplo n.º 14
0
static void CLQW_ParseDownload( QMsg& message ) {
	// read the data
	int size = message.ReadShort();
	int percent = message.ReadByte();

	if ( clc.demoplaying ) {
		if ( size > 0 ) {
			message.readcount += size;
		}
		return;	// not in demo playback
	}

	if ( size == -1 ) {
		common->Printf( "File not found.\n" );
		if ( clc.download ) {
			common->Printf( "cls.download shouldn't have been set\n" );
			FS_FCloseFile( clc.download );
			clc.download = 0;
		}
		CLQW_RequestNextDownload();
		return;
	}

	// open the file if not opened yet
	if ( !clc.download ) {
		if ( String::NCmp( clc.downloadTempName, "skins/", 6 ) ) {
			clc.download = FS_FOpenFileWrite( clc.downloadTempName );
		} else {
			char name[ 1024 ];
			sprintf( name, "qw/%s", clc.downloadTempName );
			clc.download = FS_SV_FOpenFileWrite( name );
		}

		if ( !clc.download ) {
			message.readcount += size;
			common->Printf( "Failed to open %s\n", clc.downloadTempName );
			CLQW_RequestNextDownload();
			return;
		}
	}

	FS_Write( message._data + message.readcount, size, clc.download );
	message.readcount += size;

	if ( percent != 100 ) {
		// change display routines by zoid
		// request next block
		clc.downloadPercent = percent;

		CL_AddReliableCommand( "nextdl" );
	} else {
		FS_FCloseFile( clc.download );

		// rename the temp file to it's final name
		if ( String::Cmp( clc.downloadTempName, clc.downloadName ) ) {
			if ( String::NCmp( clc.downloadTempName,"skins/",6 ) ) {
				FS_Rename( clc.downloadTempName, clc.downloadName );
			} else {
				char oldn[ MAX_OSPATH ];
				sprintf( oldn, "qw/%s", clc.downloadTempName );
				char newn[ MAX_OSPATH ];
				sprintf( newn, "qw/%s", clc.downloadName );
				FS_SV_Rename( oldn, newn );
			}
		}

		clc.download = 0;
		clc.downloadPercent = 0;

		// get another file if needed

		CLQW_RequestNextDownload();
	}
}
Ejemplo n.º 15
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];
	uint16_t block;

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

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

	if(!block && !clc.downloadBlock)
	{
		// 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 ) );
			return;
		}
	}

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

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

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

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

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

	CL_AddReliableCommand(va("nextdl %d", clc.downloadBlock), qfalse);
	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 ( clc.downloadTempName, clc.downloadName, qfalse );
		}

		// 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 ();
	}
}
Ejemplo n.º 16
0
/*
====================
LAN_SaveServersToCache
====================
*/
void LAN_SaveServersToCache() {

#if defined RTCW_SP
	// TTimo: stub, this is only relevant to MP, SP kills the servercache.dat (and favorites)
	// show_bug.cgi?id=445
	/*
	  int size;
	  fileHandle_t fileOut;
  #ifdef __MACOS__	//DAJ MacOS file typing
	  {
		  extern _MSL_IMP_EXP_C long _fcreator, _ftype;
		  _ftype = 'WlfB';
		  _fcreator = 'WlfS';
	  }
  #endif
	  fileOut = FS_SV_FOpenFileWrite("servercache.dat");
	  FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
	  FS_Write(&cls.nummplayerservers, sizeof(int), fileOut);
	  FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
	  size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers) + sizeof(cls.mplayerServers);
	  FS_Write(&size, sizeof(int), fileOut);
	  FS_Write(&cls.globalServers, sizeof(cls.globalServers), fileOut);
	  FS_Write(&cls.mplayerServers, sizeof(cls.mplayerServers), fileOut);
	  FS_Write(&cls.favoriteServers, sizeof(cls.favoriteServers), fileOut);
	  FS_FCloseFile(fileOut);
	*/
#elif defined RTCW_MP
	int size;
	fileHandle_t fileOut;
#ifdef __MACOS__    //DAJ MacOS file typing
	{
		extern _MSL_IMP_EXP_C long _fcreator, _ftype;
		_ftype = 'WlfB';
		_fcreator = 'WlfM';
	}
#endif
	fileOut = FS_SV_FOpenFileWrite( "servercache.dat" );
	FS_Write( &cls.numglobalservers, sizeof( int ), fileOut );
	FS_Write( &cls.nummplayerservers, sizeof( int ), fileOut );
	FS_Write( &cls.numfavoriteservers, sizeof( int ), fileOut );
	size = sizeof( cls.globalServers ) + sizeof( cls.favoriteServers ) + sizeof( cls.mplayerServers );
	FS_Write( &size, sizeof( int ), fileOut );
	FS_Write( &cls.globalServers, sizeof( cls.globalServers ), fileOut );
	FS_Write( &cls.mplayerServers, sizeof( cls.mplayerServers ), fileOut );
	FS_Write( &cls.favoriteServers, sizeof( cls.favoriteServers ), fileOut );
	FS_FCloseFile( fileOut );
#else
	int size;
	fileHandle_t fileOut;
	char filename[MAX_QPATH];

	if ( com_gameInfo.usesProfiles && cl_profile->string[0] ) {
		Com_sprintf( filename, sizeof( filename ), "profiles/%s/servercache.dat", cl_profile->string );
	} else {
		Q_strncpyz( filename, "servercache.dat", sizeof( filename ) );
	}

	// Arnout: moved to mod/profiles dir
	//fileOut = FS_SV_FOpenFileWrite(filename);
	fileOut = FS_FOpenFileWrite( filename );
	FS_Write( &cls.numglobalservers, sizeof( int ), fileOut );
	FS_Write( &cls.numfavoriteservers, sizeof( int ), fileOut );
	size = sizeof( cls.globalServers ) + sizeof( cls.favoriteServers );
	FS_Write( &size, sizeof( int ), fileOut );
	FS_Write( &cls.globalServers, sizeof( cls.globalServers ), fileOut );
	FS_Write( &cls.favoriteServers, sizeof( cls.favoriteServers ), fileOut );
	FS_FCloseFile( fileOut );
#endif // RTCW_XX
}
Ejemplo n.º 17
0
void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
{
    clc.cURLUsed = qtrue;
    Com_Printf("URL: %s\n", remoteURL);
    Com_DPrintf("***** CL_cURL_BeginDownload *****\n"
                "Localname: %s\n"
                "RemoteURL: %s\n"
                "****************************\n", localName, remoteURL);
    CL_cURL_Cleanup();
    Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL));
    Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName));
    Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName),
                "%s.tmp", localName);

    // Set so UI gets access to it
    Cvar_Set("cl_downloadName", localName);
    Cvar_Set("cl_downloadSize", "0");
    Cvar_Set("cl_downloadCount", "0");
    Cvar_SetValue("cl_downloadTime", cls.realtime);

    clc.downloadBlock = 0; // Starting new file
    clc.downloadCount = 0;

    clc.downloadCURL = qcurl_easy_init();
    if(!clc.downloadCURL) {
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() "
                  "failed\n");
        return;
    }
    clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName);
    if(!clc.download) {
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open "
                  "%s for writing\n", clc.downloadTempName);
        return;
    }
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download);
    if(com_developer->integer)
        qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s",
                      NET_AdrToString(clc.serverAddress)));
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s",
                      Q3_VERSION, qcurl_version()));
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION,
                      CL_cURL_CallbackWrite);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION,
                      CL_cURL_CallbackProgress);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_MAXREDIRS, 5);
    clc.downloadCURLM = qcurl_multi_init();
    if(!clc.downloadCURLM) {
        qcurl_easy_cleanup(clc.downloadCURL);
        clc.downloadCURL = NULL;
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() "
                  "failed\n");
        return;
    }
    qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL);

    if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) &&
            !clc.cURLDisconnected) {

        CL_AddReliableCommand("disconnect");
        CL_WritePacket();
        CL_WritePacket();
        CL_WritePacket();
        clc.cURLDisconnected = qtrue;
    }
}
Ejemplo n.º 18
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();
	}
}