Пример #1
0
void SVC_Info( netadr_t* from ) {
	int i, count;
	char    *gamedir;
	char infostring[MAX_INFO_STRING];
	char* g_password;
	
	if ( !SV_VerifyChallenge( Cmd_Argv( 1 ) ) ) {
		return;
	}
	
	g_password = Cvar_VariableString("g_password");
	// don't count privateclients
	count = 0;
	for ( i = sv_privateClients->integer ; i < sv_maxclients->integer ; i++ ) {
		if ( getclient(i)->state >= CS_CONNECTED ) {
			count++;
		}
	}
	
	infostring[0] = 0;
	
	// echo back the parameter to status. so servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );
	
	Info_SetValueForKey( infostring, "protocol", va("%i", protocol->integer));
	Info_SetValueForKey( infostring, "hostname", sv_hostname->string );

	Info_SetValueForKey( infostring, "mapname", mapname->string );
	
	Info_SetValueForKey( infostring, "clients", va( "%i", count ) );
	#ifdef xDEBUG
	Info_SetValueForKey( infostring, "sv_maxclients", va( "%i", sv_maxclients->integer - sv_privateClients->integer ) );
	#else
	Info_SetValueForKey( infostring, "sv_maxclients", va( "%i", sv_maxclients->integer - sv_privateClients->integer ) );
	#endif
	Info_SetValueForKey( infostring, "gametype", g_gametype->string );
	Info_SetValueForKey( infostring, "pure", va( "%i", sv_pure->integer ) );
	Info_SetValueForKey(infostring, "codextended", va("v%d", CURRENTBUILD));
	
	if ( sv_minPing->integer ) {
		Info_SetValueForKey( infostring, "minPing", va( "%i", sv_minPing->integer ) );
	}
	if ( sv_maxPing->integer ) {
		Info_SetValueForKey( infostring, "maxPing", va( "%i", sv_maxPing->integer ) );
	}
	gamedir = Cvar_VariableString( "fs_game" );
	if ( *gamedir ) {
		Info_SetValueForKey( infostring, "game", gamedir );
	}
	Info_SetValueForKey( infostring, "sv_allowAnonymous", va( "%i", sv_allowAnonymous->integer ) );

	if(*g_password)
	    Info_SetValueForKey( infostring, "pswrd", "1");
	else
	    Info_SetValueForKey( infostring, "pswrd", "0");
	
	NET_OutOfBandPrint( NS_SERVER, *from, "infoResponse\n%s", infostring );
}
Пример #2
0
void SVC_Status( netadr_t* from ) {
	char player[1024];
	char status[MAX_MSGLEN];
	int i;
	client_t    *cl;
	int/*playerState_t*/   *ps;
	int statusLength;
	int playerLength;
	char infostring[MAX_INFO_STRING];
	
	int custom_mod = 0;
	char *fs_game = Cvar_VariableString("fs_game");
	
	if(fs_game && *fs_game)
		custom_mod = 1;
	
	challenge_t* challenge;
	
	if ( !SV_VerifyChallenge( Cmd_Argv( 1 ) ) ) {
		return;
	}

	strcpy( infostring, Cvar_InfoString( 4 )); //1.5 uses 8196

	Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );

	status[0] = 0;
	statusLength = 0;

	for ( i = 0 ; i < sv_maxclients->integer ; i++ ) {
		cl = getclient(i);
		
		if ( cl->state >= CS_CONNECTED ) {
			//ps = SV_GameClientNum( i );
			Com_sprintf( player, sizeof( player ), "%i %i \"%s\"\n",
						 SV_GetClientScore(cl), cl->ping, cl->name );
			playerLength = strlen( player );
			if ( statusLength + playerLength >= sizeof( status ) ) {
				break;      // can't hold any more
			}
			strcpy( status + statusLength, player );
			statusLength += playerLength;
		}
	}
	
	#if CODPATCH == 5
	if(sv_disableClientConsole->integer)
		Info_SetValueForKey(infostring, "con_disabled", va("%i", sv_disableClientConsole->integer));
	#endif
	
	char *g_password = Cvar_VariableString("g_password");
	
	Info_SetValueForKey(infostring, "pswrd", va("%i", (g_password && *g_password) ? 1 : 0));
	
	Info_SetValueForKey(infostring, "mod", va("%i", custom_mod));
	
	NET_OutOfBandPrint( NS_SERVER, *from, "statusResponse\n%s\n%s", infostring, status );
}
Пример #3
0
/*
=================
SVC_GameCompleteStatus

NERVE - SMF - Send serverinfo cvars, etc to master servers when
game complete. Useful for tracking global player stats.
=================
*/
void SVC_GameCompleteStatus( netadr_t from ) {
	char player[1024];
	char status[MAX_MSGLEN];
	int i;
	client_t    *cl;
	playerState_t   *ps;
	int statusLength;
	int playerLength;
	char infostring[MAX_INFO_STRING];

	// ignore if we are in single player
	if ( SV_GameIsSinglePlayer() ) {
		return;
	}

	//bani - bugtraq 12534
	if ( !SV_VerifyChallenge( Cmd_Argv( 1 ) ) ) {
		return;
	}

	strcpy( infostring, Cvar_InfoString( CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE ) );

	// echo back the parameter to status. so master servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );

	// add "demo" to the sv_keywords if restricted
	if ( Cvar_VariableValue( "fs_restrict" ) ) {
		char keywords[MAX_INFO_STRING];

		Com_sprintf( keywords, sizeof( keywords ), "ettest %s",
					 Info_ValueForKey( infostring, "sv_keywords" ) );
		Info_SetValueForKey( infostring, "sv_keywords", keywords );
	}

	status[0] = 0;
	statusLength = 0;

	for ( i = 0 ; i < sv_maxclients->integer ; i++ ) {
		cl = &svs.clients[i];
		if ( cl->state >= CS_CONNECTED ) {
			ps = SV_GameClientNum( i );
			Com_sprintf( player, sizeof( player ), "%i %i \"%s\"\n",
						 ps->persistant[PERS_SCORE], cl->ping, cl->name );
			playerLength = strlen( player );
			if ( statusLength + playerLength >= sizeof( status ) ) {
				break;      // can't hold any more
			}
			strcpy( status + statusLength, player );
			statusLength += playerLength;
		}
	}

	NET_OutOfBandPrint( NS_SERVER, from, "gameCompleteStatus\n%s\n%s", infostring, status );
}
Пример #4
0
/*
================
SVC_Status

Responds with all the info that qplug or qspy can see about the server
and all connected players.  Used for getting detailed information after
the simple info query.
================
*/
void SVC_Status( netadr_t from, const Cmd::Args& args )
{
	char          player[ 1024 ];
	char          status[ MAX_MSGLEN ];
	int           i;
	client_t      *cl;
	playerState_t *ps;
	int           statusLength;
	int           playerLength;
	char          infostring[ MAX_INFO_STRING ];

	//bani - bugtraq 12534
	if ( args.Argc() > 1 && !SV_VerifyChallenge( args.Argv(1).c_str() ) )
	{
		return;
	}

	Q_strncpyz( infostring, Cvar_InfoString( CVAR_SERVERINFO, false ), MAX_INFO_STRING );

	if ( args.Argc() > 1 )
	{
		// echo back the parameter to status. so master servers can use it as a challenge
		// to prevent timed spoofed reply packets that add ghost servers
		Info_SetValueForKey( infostring, "challenge", args.Argv(1).c_str(), false );
	}

	status[ 0 ] = 0;
	statusLength = 0;

	for ( i = 0; i < sv_maxclients->integer; i++ )
	{
		cl = &svs.clients[ i ];

		if ( cl->state >= CS_CONNECTED )
		{
			ps = SV_GameClientNum( i );
			Com_sprintf( player, sizeof( player ), "%i %i \"%s\"\n", ps->persistant[ PERS_SCORE ], cl->ping, cl->name );
			playerLength = strlen( player );

			if ( statusLength + playerLength >= (int) sizeof( status ) )
			{
				break; // can't hold any more
			}

			strcpy( status + statusLength, player );
			statusLength += playerLength;
		}
	}

	NET_OutOfBandPrint( NS_SERVER, from, "statusResponse\n%s\n%s", infostring, status );
}
Пример #5
0
/*
================
SVC_Info

Responds with a short info message that should be enough to determine
if a user is interested in a server to do a full status
================
*/
void SVC_Info( netadr_t from ) {
	int i, count;
	const char    *gamedir;
	char infostring[MAX_INFO_STRING];

#if defined RTCW_MP
	const char    *antilag;

	// DHM - Nerve
#ifdef UPDATE_SERVER
	return;
#endif
#endif // RTCW_XX

#if defined RTCW_ET
	const char    *antilag;
	const char    *weaprestrict;
	const char    *balancedteams;

	// ignore if we are in single player
	if ( SV_GameIsSinglePlayer() ) {
		return;
	}
#endif // RTCW_XX

#if !defined RTCW_ET
	// ignore if we are in single player
	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER ) {
		return;
	}
#endif // RTCW_XX

#if defined RTCW_ET
	//bani - bugtraq 12534
	if ( !SV_VerifyChallenge( Cmd_Argv( 1 ) ) ) {
		return;
	}
#endif // RTCW_XX

	// don't count privateclients
	count = 0;
	for ( i = sv_privateClients->integer ; i < sv_maxclients->integer ; i++ ) {
		if ( svs.clients[i].state >= CS_CONNECTED ) {
			count++;
		}
	}

	infostring[0] = 0;

	// echo back the parameter to status. so servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );

	Info_SetValueForKey( infostring, "protocol", va( "%i", PROTOCOL_VERSION ) );
	Info_SetValueForKey( infostring, "hostname", sv_hostname->string );

#if defined RTCW_ET
	Info_SetValueForKey( infostring, "serverload", va( "%i", svs.serverLoad ) );
#endif // RTCW_XX

	Info_SetValueForKey( infostring, "mapname", sv_mapname->string );
	Info_SetValueForKey( infostring, "clients", va( "%i", count ) );
	Info_SetValueForKey( infostring, "sv_maxclients",
						 va( "%i", sv_maxclients->integer - sv_privateClients->integer ) );

#if !defined RTCW_ET
	Info_SetValueForKey( infostring, "gametype", va( "%i", sv_gametype->integer ) );
#else
	Info_SetValueForKey( infostring, "gametype", Cvar_VariableString( "g_gametype" ) );
#endif // RTCW_XX

	Info_SetValueForKey( infostring, "pure", va( "%i", sv_pure->integer ) );

	if ( sv_minPing->integer ) {
		Info_SetValueForKey( infostring, "minPing", va( "%i", sv_minPing->integer ) );
	}
	if ( sv_maxPing->integer ) {
		Info_SetValueForKey( infostring, "maxPing", va( "%i", sv_maxPing->integer ) );
	}
	gamedir = Cvar_VariableString( "fs_game" );
	if ( *gamedir ) {
		Info_SetValueForKey( infostring, "game", gamedir );
	}
	Info_SetValueForKey( infostring, "sv_allowAnonymous", va( "%i", sv_allowAnonymous->integer ) );

	// Rafael gameskill

#if !defined RTCW_ET
	Info_SetValueForKey( infostring, "gameskill", va( "%i", sv_gameskill->integer ) );
#else
//	Info_SetValueForKey (infostring, "gameskill", va ("%i", sv_gameskill->integer));
#endif // RTCW_XX

	// done

#if !defined RTCW_SP
	Info_SetValueForKey( infostring, "friendlyFire", va( "%i", sv_friendlyFire->integer ) );        // NERVE - SMF
	Info_SetValueForKey( infostring, "maxlives", va( "%i", sv_maxlives->integer ? 1 : 0 ) );        // NERVE - SMF

#if !defined RTCW_ET
	Info_SetValueForKey( infostring, "tourney", va( "%i", sv_tourney->integer ) );              // NERVE - SMF
#endif // RTCW_XX

#if defined RTCW_ET
	Info_SetValueForKey( infostring, "needpass", va( "%i", sv_needpass->integer ? 1 : 0 ) );
#endif // RTCW_XX

	Info_SetValueForKey( infostring, "gamename", GAMENAME_STRING );                               // Arnout: to be able to filter out Quake servers

	// TTimo
	antilag = Cvar_VariableString( "g_antilag" );
	if ( antilag ) {
		Info_SetValueForKey( infostring, "g_antilag", antilag );
	}
#endif // RTCW_XX

#if defined RTCW_ET
	weaprestrict = Cvar_VariableString( "g_heavyWeaponRestriction" );
	if ( weaprestrict ) {
		Info_SetValueForKey( infostring, "weaprestrict", weaprestrict );
	}

	balancedteams = Cvar_VariableString( "g_balancedteams" );
	if ( balancedteams ) {
		Info_SetValueForKey( infostring, "balancedteams", balancedteams );
	}
#endif // RTCW_XX

	NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
}
Пример #6
0
/*
==================
SV_DirectConnect

A "connect" OOB command has been received
==================
*/
void SV_DirectConnect( netadr_t from ) {
	char		userinfo[MAX_INFO_STRING];
	int			i;
	client_t	*cl, *newcl;
	client_t	temp;
	sharedEntity_t *ent;
	int			clientNum;
	int			version;
	int			qport;
	int			challenge;
	char		*password;
	int			startIndex;
	char		*denied;
	int			count;
	char		*ip;

	Com_DPrintf ("SVC_DirectConnect ()\n");

	// Check whether this client is banned.
	if ( SV_IsBanned( &from, qfalse ) )
	{
		NET_OutOfBandPrint( NS_SERVER, from, "print\nYou are banned from this server.\n" );
		Com_DPrintf( "    rejected connect from %s (banned)\n", NET_AdrToString(from) );
		return;
	}

	Q_strncpyz( userinfo, Cmd_Argv(1), sizeof(userinfo) );

	version = atoi( Info_ValueForKey( userinfo, "protocol" ) );
	if ( version != PROTOCOL_VERSION ) {
		NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i (yours is %i).\n", PROTOCOL_VERSION, version );
		Com_DPrintf ("    rejected connect from version %i\n", version);
		return;
	}

	challenge = atoi( Info_ValueForKey( userinfo, "challenge" ) );
	qport = atoi( Info_ValueForKey( userinfo, "qport" ) );

	// quick reject
	for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {

/* This was preventing sv_reconnectlimit from working.  It seems like commenting this
   out has solved the problem.  HOwever, if there is a future problem then it could
   be this.

		if ( cl->state == CS_FREE ) {
			continue;
		}
*/

		if ( NET_CompareBaseAdr( from, cl->netchan.remoteAddress )
			&& ( cl->netchan.qport == qport
			|| from.port == cl->netchan.remoteAddress.port ) ) {
			if (( svs.time - cl->lastConnectTime)
				< (sv_reconnectlimit->integer * 1000)) {
				NET_OutOfBandPrint( NS_SERVER, from, "print\nReconnect rejected : too soon\n" );
				Com_DPrintf ("%s:reconnect rejected : too soon\n", NET_AdrToString (from));
				return;
			}
			break;
		}
	}

	// don't let "ip" overflow userinfo string
	if ( NET_IsLocalAddress (from) )
		ip = "localhost";
	else
		ip = (char *)NET_AdrToString( from );
	if( ( strlen( ip ) + strlen( userinfo ) + 4 ) >= MAX_INFO_STRING ) {
		NET_OutOfBandPrint( NS_SERVER, from,
			"print\nUserinfo string length exceeded.  "
			"Try removing setu cvars from your config.\n" );
		return;
	}
	Info_SetValueForKey( userinfo, "ip", ip );

	// see if the challenge is valid (localhost clients don't need to challenge)
	if (!NET_IsLocalAddress(from))
	{
		// Verify the received challenge against the expected challenge
		if (!SV_VerifyChallenge(challenge, from))
		{
			NET_OutOfBandPrint( NS_SERVER, from, "print\nIncorrect challenge for your address.\n" );
			return;
		}
	}

	newcl = &temp;
	Com_Memset (newcl, 0, sizeof(client_t));

	// if there is already a slot for this ip, reuse it
	for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
		if ( cl->state == CS_FREE ) {
			continue;
		}
		if ( NET_CompareBaseAdr( from, cl->netchan.remoteAddress )
			&& ( cl->netchan.qport == qport
			|| from.port == cl->netchan.remoteAddress.port ) ) {
			Com_Printf ("%s:reconnect\n", NET_AdrToString (from));
			newcl = cl;
			// VVFIXME - both SOF2 and Wolf remove this call, claiming it blows away the user's info
			// disconnect the client from the game first so any flags the
			// player might have are dropped
			GVM_ClientDisconnect( newcl - svs.clients );
			//
			goto gotnewcl;
		}
	}

	// find a client slot
	// if "sv_privateClients" is set > 0, then that number
	// of client slots will be reserved for connections that
	// have "password" set to the value of "sv_privatePassword"
	// Info requests will report the maxclients as if the private
	// slots didn't exist, to prevent people from trying to connect
	// to a full server.
	// This is to allow us to reserve a couple slots here on our
	// servers so we can play without having to kick people.

	// check for privateClient password
	password = Info_ValueForKey( userinfo, "password" );
	if ( !strcmp( password, sv_privatePassword->string ) ) {
		startIndex = 0;
	} else {
		// skip past the reserved slots
		startIndex = sv_privateClients->integer;
	}

	newcl = NULL;
	for ( i = startIndex; i < sv_maxclients->integer ; i++ ) {
		cl = &svs.clients[i];
		if (cl->state == CS_FREE) {
			newcl = cl;
			break;
		}
	}

	if ( !newcl ) {
		if ( NET_IsLocalAddress( from ) ) {
			count = 0;
			for ( i = startIndex; i < sv_maxclients->integer ; i++ ) {
				cl = &svs.clients[i];
				if (cl->netchan.remoteAddress.type == NA_BOT) {
					count++;
				}
			}
			// if they're all bots
			if (count >= sv_maxclients->integer - startIndex) {
				SV_DropClient(&svs.clients[sv_maxclients->integer - 1], "only bots on server");
				newcl = &svs.clients[sv_maxclients->integer - 1];
			}
			else {
				Com_Error( ERR_FATAL, "server is full on local connect\n" );
				return;
			}
		}
		else {
			const char *SV_GetStringEdString(char *refSection, char *refName);
			NET_OutOfBandPrint( NS_SERVER, from, va("print\n%s\n", SV_GetStringEdString("MP_SVGAME","SERVER_IS_FULL")));
			Com_DPrintf ("Rejected a connection.\n");
			return;
		}
	}

	// we got a newcl, so reset the reliableSequence and reliableAcknowledge
	cl->reliableAcknowledge = 0;
	cl->reliableSequence = 0;

gotnewcl:

	// build a new connection
	// accept the new client
	// this is the only place a client_t is ever initialized
	*newcl = temp;
	clientNum = newcl - svs.clients;
	ent = SV_GentityNum( clientNum );
	newcl->gentity = ent;

	// save the challenge
	newcl->challenge = challenge;

	// save the address
	Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport);

	// save the userinfo
	Q_strncpyz( newcl->userinfo, userinfo, sizeof(newcl->userinfo) );

	// get the game a chance to reject this connection or modify the userinfo
	denied = GVM_ClientConnect( clientNum, qtrue, qfalse ); // firstTime = qtrue
	if ( denied ) {
		NET_OutOfBandPrint( NS_SERVER, from, "print\n%s\n", denied );
		Com_DPrintf ("Game rejected a connection: %s.\n", denied);
		return;
	}

	SV_UserinfoChanged( newcl );

	// send the connect packet to the client
	NET_OutOfBandPrint( NS_SERVER, from, "connectResponse" );

	Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );

	newcl->state = CS_CONNECTED;
	newcl->nextSnapshotTime = svs.time;
	newcl->lastPacketTime = svs.time;
	newcl->lastConnectTime = svs.time;

	// when we receive the first packet from the client, we will
	// notice that it is from a different serverid and that the
	// gamestate message was not just sent, forcing a retransmit
	newcl->gamestateMessageNum = -1;

	newcl->lastUserInfoChange = 0; //reset the delay
	newcl->lastUserInfoCount = 0; //reset the count

	// if this was the first client on the server, or the last client
	// the server can hold, send a heartbeat to the master.
	count = 0;
	for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
		if ( svs.clients[i].state >= CS_CONNECTED ) {
			count++;
		}
	}
	if ( count == 1 || count == sv_maxclients->integer ) {
		SV_Heartbeat_f();
	}
}
Пример #7
0
/*
================
SVC_Info

Responds with a short info message that should be enough to determine
if a user is interested in a server to do a full status
================
*/
void SVC_Info( netadr_t from, const Cmd::Args& args )
{
	int  i, count, botCount;
	char infostring[ MAX_INFO_STRING ];

	if ( args.Argc() < 2 )
	{
		return;
	}

	const char *challenge = args.Argv(1).c_str();

	/*
	 * Check whether Cmd_Argv(1) has a sane length. This was not done in the original Quake3 version which led
	 * to the Infostring bug discovered by Luigi Auriemma. See http://aluigi.altervista.org/ for the advisory.
	*/
	// A maximum challenge length of 128 should be more than plenty.
	if ( strlen( challenge ) > MAX_CHALLENGE_LEN  )
	{
		return;
	}

	//bani - bugtraq 12534
	if ( !SV_VerifyChallenge( challenge ) )
	{
		return;
	}

	SV_ResolveMasterServers();

	// don't count privateclients
	botCount = count = 0;

	for ( i = sv_privateClients->integer; i < sv_maxclients->integer; i++ )
	{
		if ( svs.clients[ i ].state >= CS_CONNECTED )
		{
			if ( SV_IsBot(&svs.clients[ i ]) )
			{
				++botCount;
			}
			else
			{
				++count;
			}
		}
	}

	infostring[ 0 ] = 0;

	// echo back the parameter to status. so servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", challenge, false );

	// If the master server listens on IPv4 and IPv6, we want to send the
	// most recent challenge received from it over the OTHER protocol
	for ( i = 0; i < MAX_MASTER_SERVERS; i++ )
	{
		// First, see if the challenge was sent by this master server
		if ( !NET_CompareBaseAdr( from, masterServerAddr[ i ].ipv4 ) && !NET_CompareBaseAdr( from, masterServerAddr[ i ].ipv6 ) )
		{
			continue;
		}

		// It was - if the saved challenge is for the other protocol, send it and record the current one
		if ( challenges[ i ].type == NA_IP || challenges[ i ].type == NA_IP6 )
		{
			if ( challenges[ i ].type != from.type )
			{
				Info_SetValueForKey( infostring, "challenge2", challenges[ i ].text, false );
				challenges[ i ].type = from.type;
				strcpy( challenges[ i ].text, challenge );
				break;
			}
		}

		// Otherwise record the current one regardless and check the next server
		challenges[ i ].type = from.type;
		strcpy( challenges[ i ].text, challenge );
	}

	Info_SetValueForKey( infostring, "protocol", va( "%i", PROTOCOL_VERSION ), false );
	Info_SetValueForKey( infostring, "hostname", sv_hostname->string, false );
	Info_SetValueForKey( infostring, "serverload", va( "%i", svs.serverLoad ), false );
	Info_SetValueForKey( infostring, "mapname", sv_mapname->string, false );
	Info_SetValueForKey( infostring, "clients", va( "%i", count ), false );
	Info_SetValueForKey( infostring, "bots", va( "%i", botCount ), false );
	Info_SetValueForKey( infostring, "sv_maxclients", va( "%i", sv_maxclients->integer - sv_privateClients->integer ), false );
	Info_SetValueForKey( infostring, "pure", va( "%i", sv_pure->integer ), false );

	if ( sv_statsURL->string[0] )
	{
		Info_SetValueForKey( infostring, "stats", sv_statsURL->string, false );
	}

#ifdef USE_VOIP

	if ( sv_voip->integer )
	{
		Info_SetValueForKey( infostring, "voip", va( "%i", sv_voip->integer ), false );
	}

#endif

	if ( sv_minPing->integer )
	{
		Info_SetValueForKey( infostring, "minPing", va( "%i", sv_minPing->integer ), false );
	}

	if ( sv_maxPing->integer )
	{
		Info_SetValueForKey( infostring, "maxPing", va( "%i", sv_maxPing->integer ), false );
	}

	Info_SetValueForKey( infostring, "gamename", GAMENAME_STRING, false );  // Arnout: to be able to filter out Quake servers

	NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
}
Пример #8
0
/*
================
SVC_Info

Responds with a short info message that should be enough to determine
if a user is interested in a server to do a full status
================
*/
void SVC_Info(netadr_t from) {
	int             i, count;
	char           *gamedir, infostring[MAX_INFO_STRING], *antilag, *weaprestrict, *balancedteams;

	// ignore if we are in single player
	if(SV_GameIsSinglePlayer()) {
		return;
	}

	//bani - bugtraq 12534
	if(!SV_VerifyChallenge(Cmd_Argv(1))) {
		return;
	}

	/*
	 * Check whether Cmd_Argv(1) has a sane length. This was not done in the original Quake3 version which led
	 * to the Infostring bug discovered by Luigi Auriemma. See http://aluigi.altervista.org/ for the advisory.
	*/
	// A maximum challenge length of 128 should be more than plenty.
	if(strlen(Cmd_Argv(1)) > 128) {
		return;
	}

#if defined (UPDATE_SERVER)
	return;
#endif

	// don't count privateclients
	count = 0;
	for(i = sv_privateClients->integer; i < sv_maxclients->integer; i++) {
		if(svs.clients[i].state >= CS_CONNECTED) {
			count++;
		}
	}

	infostring[0] = 0;

	// echo back the parameter to status. so servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey(infostring, "challenge", Cmd_Argv(1));
	Info_SetValueForKey(infostring, "protocol", va("%i", com_protocol->integer));
	Info_SetValueForKey(infostring, "hostname", sv_hostname->string);
	Info_SetValueForKey(infostring, "serverload", va("%i", svs.serverLoad));
	Info_SetValueForKey(infostring, "mapname", sv_mapname->string);
	Info_SetValueForKey(infostring, "clients", va("%i", count));
	Info_SetValueForKey(infostring, "sv_maxclients", va("%i", sv_maxclients->integer - sv_privateClients->integer));
	//Info_SetValueForKey( infostring, "gametype", va("%i", sv_gametype->integer ) );
	Info_SetValueForKey(infostring, "gametype", Cvar_VariableString("g_gametype"));
	Info_SetValueForKey(infostring, "pure", va("%i", sv_pure->integer));

#ifdef USE_VOIP
	if (sv_voip->integer) {
		Info_SetValueForKey( infostring, "voip", va("%i", sv_voip->integer ) );
	}
#endif	
	
	if(sv_minPing->integer) {
		Info_SetValueForKey(infostring, "minPing", va("%i", sv_minPing->integer));
	}
	if(sv_maxPing->integer) {
		Info_SetValueForKey(infostring, "maxPing", va("%i", sv_maxPing->integer));
	}
	gamedir = Cvar_VariableString("fs_game");
	if(*gamedir) {
		Info_SetValueForKey(infostring, "game", gamedir);
	}
	Info_SetValueForKey(infostring, "sv_allowAnonymous", va("%i", sv_allowAnonymous->integer));

	// Rafael gameskill
//  Info_SetValueForKey (infostring, "gameskill", va ("%i", sv_gameskill->integer));
	// done

	Info_SetValueForKey(infostring, "friendlyFire", va("%i", sv_friendlyFire->integer));	// NERVE - SMF
	Info_SetValueForKey(infostring, "maxlives", va("%i", sv_maxlives->integer ? 1 : 0));	// NERVE - SMF
	Info_SetValueForKey(infostring, "needpass", va("%i", sv_needpass->integer ? 1 : 0));
	Info_SetValueForKey(infostring, "gamename", GAMENAME_STRING);	// Arnout: to be able to filter out Quake servers

	// TTimo
	antilag = Cvar_VariableString("g_antilag");
	if(antilag) {
		Info_SetValueForKey(infostring, "g_antilag", antilag);
	}

	weaprestrict = Cvar_VariableString("g_heavyWeaponRestriction");
	if(weaprestrict) {
		Info_SetValueForKey(infostring, "weaprestrict", weaprestrict);
	}

	balancedteams = Cvar_VariableString("g_balancedteams");
	if(balancedteams) {
		Info_SetValueForKey(infostring, "balancedteams", balancedteams);
	}

	NET_OutOfBandPrint(NS_SERVER, from, "infoResponse\n%s", infostring);
}
Пример #9
0
/*
================
SVC_Info

Responds with a short info message that should be enough to determine
if a user is interested in a server to do a full status
================
*/
void SVC_Info( netadr_t from )
{
	int  i, count;
	char *gamedir;
	char infostring[ MAX_INFO_STRING ];

	//bani - bugtraq 12534
	if ( !SV_VerifyChallenge( Cmd_Argv( 1 ) ) )
	{
		return;
	}

	/*
	 * Check whether Cmd_Argv(1) has a sane length. This was not done in the original Quake3 version which led
	 * to the Infostring bug discovered by Luigi Auriemma. See http://aluigi.altervista.org/ for the advisory.
	*/
	// A maximum challenge length of 128 should be more than plenty.
	if ( strlen( Cmd_Argv( 1 ) ) > 128 )
	{
		return;
	}

	// don't count privateclients
	count = 0;

	for ( i = sv_privateClients->integer; i < sv_maxclients->integer; i++ )
	{
		if ( svs.clients[ i ].state >= CS_CONNECTED )
		{
			count++;
		}
	}

	infostring[ 0 ] = 0;

	// echo back the parameter to status. so servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );
	Info_SetValueForKey( infostring, "protocol", va( "%i", PROTOCOL_VERSION ) );
	Info_SetValueForKey( infostring, "hostname", sv_hostname->string );
	Info_SetValueForKey( infostring, "serverload", va( "%i", svs.serverLoad ) );
	Info_SetValueForKey( infostring, "mapname", sv_mapname->string );
	Info_SetValueForKey( infostring, "clients", va( "%i", count ) );
	Info_SetValueForKey( infostring, "sv_maxclients", va( "%i", sv_maxclients->integer - sv_privateClients->integer ) );
	Info_SetValueForKey( infostring, "pure", va( "%i", sv_pure->integer ) );

#ifdef USE_VOIP

	if ( sv_voip->integer )
	{
		Info_SetValueForKey( infostring, "voip", va( "%i", sv_voip->integer ) );
	}

#endif

	if ( sv_minPing->integer )
	{
		Info_SetValueForKey( infostring, "minPing", va( "%i", sv_minPing->integer ) );
	}

	if ( sv_maxPing->integer )
	{
		Info_SetValueForKey( infostring, "maxPing", va( "%i", sv_maxPing->integer ) );
	}

	gamedir = Cvar_VariableString( "fs_game" );

	if ( *gamedir )
	{
		Info_SetValueForKey( infostring, "game", gamedir );
	}

	Info_SetValueForKey( infostring, "gamename", GAMENAME_STRING );  // Arnout: to be able to filter out Quake servers

	NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
}