📄 sv_rankings.c
字号:
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 + -