⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sv_rankings.c

📁 3D 游戏界的大牛人 John Carmack 终于放出了 Q3 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	GR_STATUS status;
	qboolean rVal;
	ranked_player_t* ranked_player;
	int i;

	assert( s_ranked_players );
	assert( s_ranked_players[index].grank_status != QGR_STATUS_ACTIVE );

	rVal = qfalse;
	
	if( !s_rankings_active )
	{
		Com_DPrintf( "SV_RankUserValidate: Not ready to validate\n" );
		s_ranked_players[index].grank_status = QGR_STATUS_ERROR;
		return rVal;
	}
	
	ranked_player = &(s_ranked_players[index]);
	
	if ( (player_id != NULL) && (key != NULL))
	{
		// the real player_id and key is set when SV_RankJoinGameCBF
		// is called we do this so that SV_RankUserValidate
		// can be shared by both server side login and client side login
		
		// for client side logined in players
		// server is creating GR_OPT_PLAYERCONTEXT
		init = GRankInit( 0, SV_RankGameKey, GR_OPT_POLL, GR_OPT_END );
		ranked_player->context   = init.context;
		s_rankings_contexts++;
		Com_DPrintf( "SV_RankUserValidate(); s_rankings_contexts=%d\n",s_rankings_contexts );
		Com_DPrintf( "SV_RankUserValidate(); s_ranked_players[%d].context=%d\n",index,init.context );
		
		// uudecode player id and player token
		ranked_player->player_id = SV_RankDecodePlayerID(player_id);
		Com_DPrintf( "SV_RankUserValidate(); ranked_player->player_id =%u\n", (uint32_t)ranked_player->player_id );
		SV_RankDecodePlayerKey(key, ranked_player->token);
		
		// save name and check for duplicates
		Q_strncpyz( ranked_player->name, name, sizeof(ranked_player->name) );
		for( i = 0; i < sv_maxclients->value; i++ )
		{
			if( (i != index) && (s_ranked_players[i].grank_status == QGR_STATUS_ACTIVE) && 
				(strcmp( s_ranked_players[i].name, name ) == 0) )
			{
				Com_DPrintf( "SV_RankUserValidate: Duplicate login\n" );
				ranked_player->grank_status = QGR_STATUS_NO_USER;
				ranked_player->final_status = QGR_STATUS_NEW;
				ranked_player->grank = 0;
				return qfalse;
			}
		}

		// then validate
		status  = GRankPlayerValidate(
							s_server_context,
							ranked_player->player_id, 
							ranked_player->token,
							token_len,
							GR_OPT_PLAYERCONTEXT,
							ranked_player->context,
							GR_OPT_END);
	}
	else
	{
		// make server side login (bots) happy
		status = GR_STATUS_OK;
	}

	if (status == GR_STATUS_OK)
	{
 		ranked_player->grank_status = QGR_STATUS_ACTIVE;
		ranked_player->final_status = QGR_STATUS_NEW;
		ranked_player->grank = rank;
		rVal = qtrue;
	}
	else if (status == GR_STATUS_INVALIDUSER)
	{
		ranked_player->grank_status = QGR_STATUS_INVALIDUSER;
		ranked_player->final_status = QGR_STATUS_NEW;
		ranked_player->grank = 0;
		rVal = qfalse;
	}
	else
	{
		SV_RankError( "SV_RankUserValidate: Unexpected status %s",
			SV_RankStatusString( status ) );
		s_ranked_players[index].grank_status = QGR_STATUS_ERROR;
		ranked_player->grank = 0;
	}
	
	return rVal;
}

/*
================
SV_RankUserLogout
================
*/
void SV_RankUserLogout( int index )
{
	GR_STATUS	status;
	GR_STATUS	cleanup_status;

	if( !s_rankings_active )
	{
		return;
	}

	assert( index >= 0 );
	assert( index < sv_maxclients->value );
	assert( s_ranked_players );

	if( s_ranked_players[index].context == 0 ) {
		return;
	}

	Com_DPrintf( "SV_RankUserLogout( %d );\n", index );

	// masqueraded player may not be active yet, if they fail validation, 
	// but still they have a context needs to be cleaned 
	// what matters is the s_ranked_players[index].context
	
	// send reports, proceed to SV_RankSendReportsCBF
	status = GRankSendReportsAsync
		( 
			s_ranked_players[index].context,
			0,
			SV_RankSendReportsCBF,
			(void*)&s_ranked_players[index], 
			GR_OPT_END
		);
		
	if( status == GR_STATUS_PENDING )
	{
		s_ranked_players[index].grank_status = QGR_STATUS_PENDING;
		s_ranked_players[index].final_status = QGR_STATUS_NEW;
	}
	else
	{
		SV_RankError( "SV_RankUserLogout: Expected GR_STATUS_PENDING, got %s", 
			SV_RankStatusString( status ) );

		cleanup_status = GRankCleanupAsync
			(
				s_ranked_players[index].context,
				0,
				SV_RankCleanupCBF,
				(void*)&s_ranked_players[index],
				GR_OPT_END
			);
		
		if( cleanup_status != GR_STATUS_PENDING )
		{
			SV_RankError( "SV_RankUserLogout: Expected "
				"GR_STATUS_PENDING from GRankCleanupAsync, got %s", 
				SV_RankStatusString( cleanup_status ) );
			SV_RankCloseContext( &(s_ranked_players[index]) );
		}
	}
}

/*
================
SV_RankReportInt
================
*/
void SV_RankReportInt( int index1, int index2, int key, int value, 
	qboolean accum )
{
	GR_STATUS	status;
	GR_CONTEXT	context;
	uint64_t	match;
	uint64_t	user1;
	uint64_t	user2;
	int			opt_accum;

	if( !s_rankings_active )
	{
		return;
	}

	assert( index1 >= -1 );
	assert( index1 < sv_maxclients->value );
	assert( index2 >= -1 );
	assert( index2 < sv_maxclients->value );
	assert( s_ranked_players );

//	Com_DPrintf( "SV_RankReportInt( %d, %d, %d, %d, %d );\n", index1, index2, 
//		key, value, accum );

	// get context, match, and player_id for player index1
	if( index1 == -1 )
	{
		context = s_server_context;
		match = s_server_match;
		user1 = 0;
	}
	else
	{
		if( s_ranked_players[index1].grank_status != QGR_STATUS_ACTIVE )
		{
			Com_DPrintf( "SV_RankReportInt: Expecting QGR_STATUS_ACTIVE"
				" Got Unexpected status %d for player %d\n", 
				s_ranked_players[index1].grank_status, index1 );
			return;
		}
	
		context = s_ranked_players[index1].context;
		match = s_ranked_players[index1].match;
		user1 = s_ranked_players[index1].player_id;
	}

	// get player_id for player index2
	if( index2 == -1 )
	{
		user2 = 0;
	}
	else
	{
		if( s_ranked_players[index2].grank_status != QGR_STATUS_ACTIVE )
		{
			Com_DPrintf( "SV_RankReportInt: Expecting QGR_STATUS_ACTIVE"
				" Got Unexpected status %d for player %d\n", 
				s_ranked_players[index2].grank_status, index2 );
			return;
		}

		user2 = s_ranked_players[index2].player_id;
	}

	opt_accum = accum ? GR_OPT_ACCUM : GR_OPT_END;
	
	status = GRankReportInt
		(
			context,
			match,
			user1, 
			user2,
			key,
			value,
			opt_accum,
			GR_OPT_END
		);
		
	if( status != GR_STATUS_OK )
	{
		SV_RankError( "SV_RankReportInt: Unexpected status %s",
			SV_RankStatusString( status ) );
	}

	if( user2 != 0 )
	{
		context = s_ranked_players[index2].context;
		match   = s_ranked_players[index2].match;
		
		status = GRankReportInt
			(
				context,
				match,
				user1, 
				user2,
				key,
				value,
				opt_accum,
				GR_OPT_END
			);
			
		if( status != GR_STATUS_OK )
		{
			SV_RankError( "SV_RankReportInt: Unexpected status %s",
				SV_RankStatusString( status ) );
		}
	}
}

/*
================
SV_RankReportStr
================
*/
void SV_RankReportStr( int index1, int index2, int key, char* value )
{
	GR_STATUS	status;
	GR_CONTEXT	context;
	uint64_t	match;
	uint64_t	user1;
	uint64_t	user2;

	if( !s_rankings_active )
	{
		return;
	}

	assert( index1 >= -1 );
	assert( index1 < sv_maxclients->value );
	assert( index2 >= -1 );
	assert( index2 < sv_maxclients->value );
	assert( s_ranked_players );

//	Com_DPrintf( "SV_RankReportStr( %d, %d, %d, \"%s\" );\n", index1, index2, 
//		key, value );
	
	// get context, match, and player_id for player index1
	if( index1 == -1 )
	{
		context = s_server_context;
		match = s_server_match;
		user1 = 0;
	}
	else
	{
		if( s_ranked_players[index1].grank_status != QGR_STATUS_ACTIVE )
		{
			Com_DPrintf( "SV_RankReportStr: Unexpected status %d\n", 
				s_ranked_players[index1].grank_status );
			return;
		}
	
		context = s_ranked_players[index1].context;
		match = s_ranked_players[index1].match;
		user1 = s_ranked_players[index1].player_id;
	}

	// get player_id for player index2
	if( index2 == -1 )
	{
		user2 = 0;
	}
	else
	{
		if( s_ranked_players[index2].grank_status != QGR_STATUS_ACTIVE )
		{
			Com_DPrintf( "SV_RankReportStr: Unexpected status %d\n", 
				s_ranked_players[index2].grank_status );
			return;
		}

		user2 = s_ranked_players[index2].player_id;
	}

	status = GRankReportStr
		(
			context,
			match,
			user1,
			user2,
			key,
			value,
			GR_OPT_END
		);
		
	if( status != GR_STATUS_OK )
	{
		SV_RankError( "SV_RankReportStr: Unexpected status %s",
			SV_RankStatusString( status ) );
	}
	
	if( user2 != 0 )
	{
		context = s_ranked_players[index2].context;
		match = s_ranked_players[index2].match;
		
		status = GRankReportStr
			(
				context,
				match,
				user1, 
				user2,
				key,
				value,
				GR_OPT_END
			);
			
		if( status != GR_STATUS_OK )
		{
			SV_RankError( "SV_RankReportInt: Unexpected status %s",
				SV_RankStatusString( status ) );
		}
	}
}

/*
================
SV_RankQuit
================
*/
void SV_RankQuit( void )
{
	int	i;
	int j = 0;	
	// yuck
	
	while( s_rankings_contexts > 1 )
	{
		assert(s_ranked_players);
		if( s_ranked_players != NULL )
		{
			for( i = 0; i < sv_maxclients->value; i++ )
			{
				// check for players that weren't yet active in SV_RankEnd
				if( s_ranked_players[i].grank_status == QGR_STATUS_ACTIVE )
				{
					SV_RankUserLogout( i );
					Com_DPrintf( "SV_RankQuit: SV_RankUserLogout %d\n",i );
				}
				else
				{
					if( s_ranked_players[i].context )
					{
						GR_STATUS cleanup_status;
						cleanup_status = GRankCleanupAsync
							(
								s_ranked_players[i].context,
								0,
								SV_RankCleanupCBF,
								(void*)&(s_ranked_players[i]),
								GR_OPT_END
							);
						
						if( cleanup_status != GR_STATUS_PENDING )
						{
							SV_RankError( "SV_RankQuit: Expected "
								"GR_STATUS_PENDING from GRankCleanupAsync, got %s", 
								SV_RankStatusString( cleanup_status ) );
						}
					}
				}
			}
		}
		SV_RankPoll();
		
		// should've finished by now
		assert( (j++) < 68 );
	}
}

/*
==============================================================================

Private Functions

==============================================================================
*/

/*
=================
SV_RankNewGameCBF
=================
*/
static void SV_RankNewGameCBF( GR_NEWGAME* gr_newgame, void* cbf_arg )
{
	GR_MATCH	match;
	int			i;
	
	assert( gr_newgame != NULL );
	assert( cbf_arg == NULL );

	Com_DPrintf( "SV_RankNewGameCBF( %08X, %08X );\n", gr_newgame, cbf_arg );
	
	if( gr_newgame->status == GR_STATUS_OK )
	{
		char info[MAX_INFO_STRING];
		char gameid[sizeof(s_ranked_players[i].game_id) * 4 / 3 + 2];
		
		// save game id
		s_rankings_game_id = gr_newgame->game_id;
		
		// encode gameid 
		memset(gameid,0,sizeof(gameid));
		SV_RankEncodeGameID(s_rankings_game_id,gameid,sizeof(gameid));
		
		// set CS_GRANK rankingsGameID to pass to client
		memset(info,0,sizeof(info));
		Info_SetValueForKey( info, "rankingsGameKey", s_rankings_game_key );
		Info_SetValueForKey( info, "rankingsGameID", gameid );
		SV_SetConfigstring( CS_GRANK, info );

		// initialize client status
		for( i = 0; i < sv_maxclients->value; i++ )
			s_ranked_players[i].grank_status = QGR_STATUS_NEW;

		// start new match
		match = GRankStartMatch( s_server_context );
		s_server_match = match.match;

		// ready to go
		s_rankings_active = qtrue;
		Cvar_Set( "sv_rankingsActive", "1" );

	}
	else if( gr_newgame->status == GR_STATUS_BADLEAGUE )
	{
		SV_RankError( "SV_RankNewGameCBF: Invalid League name\n" );
	}
	else
	{
		//GRank handle new game failure
		// force  SV_RankEnd() to run
		//SV_RankEnd();
		SV_RankError( "SV_RankNewGameCBF: Unexpected status %s", 
			SV_RankStatusString( gr_newgame->status ) );
	}
}

/*
================
SV_RankUserCBF
================
*/
static void SV_RankUserCBF( GR_LOGIN* gr_login, void* cbf_arg )
{
	ranked_player_t*	ranked_player;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -