2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# include "sys_lobby.h"
# include "sys_voicechat.h"
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : SaveDisconnectedUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : SaveDisconnectedUser ( const lobbyUser_t & user )
{
2012-11-26 18:58:24 +00:00
bool found = false ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < disconnectedUsers . Num ( ) ; i + + )
{
if ( user . lobbyUserID . CompareIgnoreLobbyType ( disconnectedUsers [ i ] . lobbyUserID ) )
{
2012-11-26 18:58:24 +00:00
found = true ;
memcpy ( disconnectedUsers [ i ] . gamertag , user . gamertag , sizeof ( user . gamertag ) ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! found )
{
disconnectedUser_t & du = disconnectedUsers . Alloc ( ) ;
2012-11-26 18:58:24 +00:00
du . lobbyUserID = user . lobbyUserID ;
memcpy ( du . gamertag , user . gamertag , sizeof ( user . gamertag ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : AllocUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUser_t * idLobby : : AllocUser ( const lobbyUser_t & defaults )
{
if ( ! verify ( freeUsers . Num ( ) > 0 ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Error ( " Out of session users " ) ; // This shouldn't be possible
}
2012-11-28 15:47:07 +00:00
lobbyUser_t * user = freeUsers [ freeUsers . Num ( ) - 1 ] ;
2012-11-26 18:58:24 +00:00
freeUsers . SetNum ( freeUsers . Num ( ) - 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Set defaults
* user = defaults ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
userList . Append ( user ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( userList . Num ( ) = = userPool . Max ( ) - freeUsers . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return user ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : FreeUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : FreeUser ( lobbyUser_t * user )
{
if ( ! verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! VerifyUser ( user ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SaveDisconnectedUser ( * user ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
verify ( userList . Remove ( user ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
freeUsers . Append ( user ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : FreeAllUsers
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : FreeAllUsers ( )
{
for ( int i = userList . Num ( ) - 1 ; i > = 0 ; i - - )
{
2012-11-26 18:58:24 +00:00
FreeUser ( userList [ i ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( userList . Num ( ) = = 0 ) ;
assert ( freeUsers . Num ( ) = = userPool . Max ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RegisterUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RegisterUser ( lobbyUser_t * lobbyUser )
{
if ( lobbyUser - > isBot )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Register the user with the various managers
bool isLocal = IsSessionUserLocal ( lobbyUser ) ;
2012-11-28 15:47:07 +00:00
if ( lobbyBackend ! = NULL )
{
2012-11-26 18:58:24 +00:00
lobbyBackend - > RegisterUser ( lobbyUser , isLocal ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
sessionCB - > GetVoiceChat ( ) - > RegisterTalker ( lobbyUser , lobbyType , isLocal ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : UnregisterUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : UnregisterUser ( lobbyUser_t * lobbyUser )
{
if ( lobbyUser - > isBot )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( lobbyUser - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
bool isLocal = IsSessionUserLocal ( lobbyUser ) ;
2012-11-28 15:47:07 +00:00
if ( lobbyBackend ! = NULL )
{
2012-11-26 18:58:24 +00:00
lobbyBackend - > UnregisterUser ( lobbyUser , isLocal ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
sessionCB - > GetVoiceChat ( ) - > UnregisterTalker ( lobbyUser , lobbyType , isLocal ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : VerifyUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : VerifyUser ( const lobbyUser_t * lobbyUser ) const
{
if ( ! verify ( userList . FindIndex ( const_cast < lobbyUser_t * > ( lobbyUser ) ) ! = - 1 ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : IsSessionUserLocal
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : IsSessionUserLocal ( const lobbyUser_t * lobbyUser ) const
{
if ( ! verify ( lobbyUser ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! VerifyUser ( lobbyUser ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// This user is local if the peerIndex matches what our peerIndex is on the host
return ( lobbyUser - > peerIndex = = peerIndexOnHost ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : IsSessionUserIndexLocal
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : IsSessionUserIndexLocal ( int i ) const
{
2012-11-26 18:58:24 +00:00
return IsSessionUserLocal ( GetLobbyUser ( i ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserIndexByID
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idLobby : : GetLobbyUserIndexByID ( lobbyUserID_t lobbyUserId , bool ignoreLobbyType ) const
{
if ( ! lobbyUserId . IsValid ( ) )
{
2012-11-26 18:58:24 +00:00
return - 1 ;
}
assert ( lobbyUserId . GetLobbyType ( ) = = lobbyType | | ignoreLobbyType ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; + + i )
{
if ( ignoreLobbyType )
{
if ( GetLobbyUser ( i ) - > lobbyUserID . CompareIgnoreLobbyType ( lobbyUserId ) )
{
2012-11-26 18:58:24 +00:00
return i ;
}
continue ;
}
2012-11-28 15:47:07 +00:00
if ( GetLobbyUser ( i ) - > lobbyUserID = = lobbyUserId )
{
2012-11-26 18:58:24 +00:00
return i ;
}
}
return - 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserByID
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUser_t * idLobby : : GetLobbyUserByID ( lobbyUserID_t lobbyUserID , bool ignoreLobbyType )
{
2012-11-26 18:58:24 +00:00
int index = GetLobbyUserIndexByID ( lobbyUserID , ignoreLobbyType ) ;
2012-11-28 15:47:07 +00:00
if ( index = = - 1 )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return GetLobbyUser ( index ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : CreateLobbyUserFromLocalUser
This functions just defaults the session users to the signin manager local users
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUser_t idLobby : : CreateLobbyUserFromLocalUser ( const idLocalUser * localUser )
{
2012-11-26 18:58:24 +00:00
lobbyUser_t lobbyUser ;
idStr : : Copynz ( lobbyUser . gamertag , localUser - > GetGamerTag ( ) , sizeof ( lobbyUser . gamertag ) ) ;
lobbyUser . peerIndex = - 1 ;
lobbyUser . lobbyUserID = lobbyUserID_t ( localUser - > GetLocalUserHandle ( ) , lobbyType ) ; // Generate the lobby using a combination of local user id, and lobby type
lobbyUser . disconnecting = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// If we are in a game lobby (or dedicated game state lobby), and we have a party lobby running, assume we can grab the party token from our equivalent user in the party.
2012-11-28 15:47:07 +00:00
if ( ( lobbyType = = TYPE_GAME | | lobbyType = = TYPE_GAME_STATE ) & & sessionCB - > GetPartyLobby ( ) . IsLobbyActive ( ) )
{
if ( ( sessionCB - > GetPartyLobby ( ) . parms . matchFlags & MATCH_REQUIRE_PARTY_LOBBY ) & & ! ( sessionCB - > GetPartyLobby ( ) . parms . matchFlags & MATCH_PARTY_INVITE_PLACEHOLDER ) )
{
2012-11-26 18:58:24 +00:00
// copy some things from my party user
const int myPartyUserIndex = sessionCB - > GetPartyLobby ( ) . GetLobbyUserIndexByLocalUserHandle ( lobbyUser . lobbyUserID . GetLocalUserHandle ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( verify ( myPartyUserIndex > = 0 ) ) // Just in case
{
lobbyUser_t * myPartyUser = sessionCB - > GetPartyLobby ( ) . GetLobbyUser ( myPartyUserIndex ) ;
if ( myPartyUser ! = NULL )
{
2012-11-26 18:58:24 +00:00
lobbyUser . partyToken = myPartyUser - > partyToken ;
}
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
lobbyUser . UpdateClientMutableData ( localUser ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
NET_VERBOSE_PRINT ( " NET: CreateLobbyUserFromLocalUser: party %08x name %s (%s) \n " , lobbyUser . partyToken , lobbyUser . gamertag , GetLobbyName ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return lobbyUser ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : InitSessionUsersFromLocalUsers
This functions just defaults the session users to the signin manager local users
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : InitSessionUsersFromLocalUsers ( bool onlineMatch )
{
2012-11-26 18:58:24 +00:00
assert ( lobbyBackend ! = NULL ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// First, clear all session users of this session type
FreeAllUsers ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Copy all local users from sign in mgr to the session user list
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < sessionCB - > GetSignInManager ( ) . GetNumLocalUsers ( ) ; i + + )
{
idLocalUser * localUser = sessionCB - > GetSignInManager ( ) . GetLocalUserByIndex ( i ) ;
2012-11-26 18:58:24 +00:00
// Make sure this user can join lobbies
2012-11-28 15:47:07 +00:00
if ( onlineMatch & & ! localUser - > CanPlayOnline ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
lobbyUser_t lobbyUser = CreateLobbyUserFromLocalUser ( localUser ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Append this new session user to the session user list
2012-11-28 15:47:07 +00:00
lobbyUser_t * createdUser = AllocUser ( lobbyUser ) ;
2012-11-26 18:58:24 +00:00
// Get the migration game data if this is a migrated hosting
2012-11-28 15:47:07 +00:00
if ( verify ( createdUser ! = NULL ) & & migrationInfo . persistUntilGameEndsData . wasMigratedHost )
{
2012-11-26 18:58:24 +00:00
createdUser - > migrationGameData = migrationInfo . persistUntilGameEndsData . ourGameData ;
NET_VERBOSE_PRINT ( " NET: Migration game data set for local user %s at index %d \n " , createdUser - > gamertag , migrationInfo . persistUntilGameEndsData . ourGameData ) ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserIndexByLocalUserHandle
Takes a local user handle , and converts to a session user
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idLobby : : GetLobbyUserIndexByLocalUserHandle ( const localUserHandle_t localUserHandle ) const
{
2012-11-26 18:58:24 +00:00
// Find the session user that uses this input device index
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; i + + )
{
if ( ! IsSessionUserIndexLocal ( i ) )
{
2012-11-26 18:58:24 +00:00
continue ; // We only want local users
}
2012-11-28 15:47:07 +00:00
if ( GetLobbyUser ( i ) - > lobbyUserID . GetLocalUserHandle ( ) = = localUserHandle )
{
2012-11-26 18:58:24 +00:00
return i ; // Found it
}
}
return - 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLocalUserFromLobbyUserIndex
This takes a session user , and converts to a local user
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idLocalUser * idLobby : : GetLocalUserFromLobbyUserIndex ( int lobbyUserIndex )
{
if ( lobbyUserIndex < 0 | | lobbyUserIndex > = GetNumLobbyUsers ( ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
if ( ! IsSessionUserIndexLocal ( lobbyUserIndex ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
lobbyUser_t * lobbyUser = GetLobbyUser ( lobbyUserIndex ) ;
if ( lobbyUser = = NULL )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
return sessionCB - > GetSignInManager ( ) . GetLocalUserByHandle ( lobbyUser - > lobbyUserID . GetLocalUserHandle ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetSessionUserFromLocalUser
Takes a local user , and converts to a session user
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUser_t * idLobby : : GetSessionUserFromLocalUser ( const idLocalUser * localUser )
{
if ( localUser = = NULL )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int sessionUserIndex = GetLobbyUserIndexByLocalUserHandle ( localUser - > GetLocalUserHandle ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( sessionUserIndex ! = - 1 )
{
2012-11-26 18:58:24 +00:00
assert ( IsSessionUserIndexLocal ( sessionUserIndex ) ) ;
return GetLobbyUser ( sessionUserIndex ) ;
}
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RemoveUsersWithDisconnectedPeers
Go through each user , and remove the ones that have a peer marked as disconnected
2012-11-28 15:47:07 +00:00
NOTE - This should only be called from the host . The host will call RemoveSessionUsersByIDList ,
2012-11-26 18:58:24 +00:00
which will forward the action to the connected peers .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RemoveUsersWithDisconnectedPeers ( )
{
if ( ! verify ( IsHost ( ) ) )
{
2012-11-26 18:58:24 +00:00
// We're not allowed to do this unless we are the host of this session type
// If we are the host, RemoveSessionUsersByIDList will forward the call to peers.
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idList < lobbyUserID_t > removeList ;
2012-11-28 15:47:07 +00:00
for ( int u = 0 ; u < GetNumLobbyUsers ( ) ; u + + )
{
lobbyUser_t * user = GetLobbyUser ( u ) ;
if ( ! verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( IsSessionUserIndexLocal ( u ) | | user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = - 1 )
{
// Wanting to know if this actually happens.
2012-11-26 18:58:24 +00:00
// If this is a user on the hosts machine, IsSessionUserIndexLocal should catch it above.
2012-11-28 15:47:07 +00:00
assert ( false ) ;
2012-11-26 18:58:24 +00:00
// The user is on the host.
// The host's peer is disconnected via other mechanisms that I don't have a firm
// grasp on yet.
continue ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex > = peers . Num ( ) )
{
2012-11-26 18:58:24 +00:00
// TTimo - I am hitting this in ~12 client games for some reason?
// only throwing an assertion in debug, with no crashing, so adding a warning verbose
idLib : : Warning ( " idLobby::RemoveUsersWithDisconnectedPeers: user %d %s is out of range in the peers list (%d elements) " , u , user - > gamertag , peers . Num ( ) ) ;
continue ;
}
2012-11-28 15:47:07 +00:00
peer_t & peer = peers [ user - > peerIndex ] ;
if ( peer . GetConnectionState ( ) ! = CONNECTION_ESTABLISHED )
{
2012-11-26 18:58:24 +00:00
removeList . Append ( user - > lobbyUserID ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
RemoveSessionUsersByIDList ( removeList ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RemoveSessionUsersByIDList
This is the choke point for removing users from a session .
It will handle all the housekeeping of removing from various platform lists ( xsession user tracking , etc ) .
Called from both host and client .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RemoveSessionUsersByIDList ( idList < lobbyUserID_t > & usersToRemoveByID )
{
2012-11-26 18:58:24 +00:00
assert ( lobbyBackend ! = NULL | | usersToRemoveByID . Num ( ) = = 0 ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < usersToRemoveByID . Num ( ) ; i + + )
{
for ( int u = 0 ; u < GetNumLobbyUsers ( ) ; u + + )
{
lobbyUser_t * user = GetLobbyUser ( u ) ;
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
// User already disconnected from session but not removed from the list.
// This will happen when users are removed during the game.
continue ;
}
2012-11-28 15:47:07 +00:00
if ( user - > lobbyUserID = = usersToRemoveByID [ i ] )
{
if ( lobbyType = = TYPE_GAME )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " NET: %s left the game. \n " , user - > gamertag ) ;
2012-11-28 15:47:07 +00:00
}
else if ( lobbyType = = TYPE_PARTY )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " NET: %s left the party. \n " , user - > gamertag ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UnregisterUser ( user ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Save the user so we can still get his gamertag, which may be needed for
// a disconnection HUD message.
SaveDisconnectedUser ( * user ) ;
FreeUser ( user ) ;
break ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( usersToRemoveByID . Num ( ) > 0 & & IsHost ( ) )
{
if ( lobbyBackend ! = NULL )
{
2012-11-26 18:58:24 +00:00
lobbyBackend - > UpdateLobbySkill ( GetAverageSessionLevel ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// If we are the host, send a message to all peers with a list of users who have disconnected
byte buffer [ idPacketProcessor : : MAX_MSG_SIZE ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
msg . WriteByte ( usersToRemoveByID . Num ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < usersToRemoveByID . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
usersToRemoveByID [ i ] . WriteToMsg ( msg ) ;
}
2012-11-28 15:47:07 +00:00
for ( int p = 0 ; p < peers . Num ( ) ; p + + )
{
2012-11-26 18:58:24 +00:00
QueueReliableMessage ( p , RELIABLE_USER_DISCONNECTED , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : SendPeersMicStatusToNewUsers
Sends each current user mic status to the newly added peer .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : SendPeersMicStatusToNewUsers ( int peerNumber )
{
if ( ! IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg outmsg ( buffer , sizeof ( buffer ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Count up how many users will be in the msg
int numUsersInMsg = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; + + i )
{
lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > isBot )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = peerNumber )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numUsersInMsg + + ;
}
2012-11-28 15:47:07 +00:00
if ( numUsersInMsg = = 0 )
{
2012-11-26 18:58:24 +00:00
return ; // Nothing to do
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
outmsg . WriteLong ( numUsersInMsg ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; + + i )
{
lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > isBot )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = peerNumber )
{
2012-11-26 18:58:24 +00:00
continue ;
}
int talkerIndex = sessionCB - > GetVoiceChat ( ) - > FindTalkerByUserId ( user - > lobbyUserID , lobbyType ) ;
bool state = sessionCB - > GetVoiceChat ( ) - > GetHeadsetState ( talkerIndex ) ;
idLib : : Printf ( " Packing headset state %d for user %d %s \n " , state , i , user - > gamertag ) ;
user - > lobbyUserID . WriteToMsg ( outmsg ) ;
outmsg . WriteBool ( state ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Sending headset states to new peer %d \n " , peerNumber ) ;
QueueReliableMessage ( peerNumber , RELIABLE_HEADSET_STATE , outmsg . GetReadData ( ) , outmsg . GetSize ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : SendNewUsersToPeers
Sends a range of users to the current list of peers .
The host calls this when he receives new users , to forward the list to the other peers .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : SendNewUsersToPeers ( int skipPeer , int userStart , int numUsers )
{
if ( ! IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( GetNumLobbyUsers ( ) - userStart = = numUsers ) ;
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg outmsg ( buffer , sizeof ( buffer ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Write number of users
outmsg . WriteByte ( numUsers ) ;
// Fill up the msg with all the users
2012-11-28 15:47:07 +00:00
for ( int u = userStart ; u < GetNumLobbyUsers ( ) ; u + + )
{
2012-11-26 18:58:24 +00:00
GetLobbyUser ( u ) - > WriteToMsg ( outmsg ) ;
}
// Send the msg to all peers (except the skipPeer, or peers not connected to this session type)
2012-11-28 15:47:07 +00:00
for ( int p = 0 ; p < peers . Num ( ) ; p + + )
{
if ( p = = skipPeer | | peers [ p ] . GetConnectionState ( ) ! = CONNECTION_ESTABLISHED )
{
2012-11-26 18:58:24 +00:00
continue ; // If they are not connected in this session type, don't send anything to them.
}
QueueReliableMessage ( p , RELIABLE_USER_CONNECTED , outmsg . GetReadData ( ) , outmsg . GetSize ( ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : AllocLobbyUserSlotForBot
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUserID_t idLobby : : AllocLobbyUserSlotForBot ( const char * botName )
{
2012-11-26 18:58:24 +00:00
lobbyUser_t botSessionUser ;
botSessionUser . peerIndex = peerIndexOnHost ;
botSessionUser . isBot = true ;
botSessionUser . disconnecting = false ;
idStr : : Copynz ( botSessionUser . gamertag , botName , sizeof ( botSessionUser . gamertag ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localUserHandle_t localUserHandle ( session - > GetSignInManager ( ) . GetUniqueLocalUserHandle ( botSessionUser . gamertag ) ) ;
botSessionUser . lobbyUserID = lobbyUserID_t ( localUserHandle , lobbyType ) ;
2012-11-28 15:47:07 +00:00
lobbyUser_t * botUser = NULL ;
2012-11-26 18:58:24 +00:00
int sessionUserIndex = - 1 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// First, try to replace a disconnected user
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; + + i )
{
if ( IsLobbyUserDisconnected ( i ) )
{
lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
* user = botSessionUser ;
botUser = user ;
sessionUserIndex = i ;
break ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( botUser = = NULL )
{
if ( freeUsers . Num ( ) = = 0 )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " NET: Out Of Session Users - Can't Add Bot %s! " , botName ) ;
return lobbyUserID_t ( ) ;
}
botUser = AllocUser ( botSessionUser ) ;
sessionUserIndex = userList . Num ( ) - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( ! verify ( botUser ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " NET: Can't Find Session Slot For Bot! " ) ;
return lobbyUserID_t ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
NET_VERBOSE_PRINT ( " NET: Created Bot %s At Index %d \n " , botUser - > gamertag , sessionUserIndex ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
SendNewUsersToPeers ( peerIndexOnHost , userList . Num ( ) - 1 , 1 ) ; // bot has been added to the lobby user list - update the peers so that they can see the bot too.
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return GetLobbyUser ( sessionUserIndex ) - > lobbyUserID ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RemoveBotFromLobbyUserList
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RemoveBotFromLobbyUserList ( lobbyUserID_t lobbyUserID )
{
2012-11-26 18:58:24 +00:00
const int index = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
lobbyUser_t * botUser = GetLobbyUser ( index ) ;
if ( botUser = = NULL )
{
2012-11-26 18:58:24 +00:00
assert ( false ) ;
idLib : : Warning ( " RemoveBotFromLobbyUserList: Invalid User Index! " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! botUser - > isBot )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " RemoveBotFromLobbyUserList: User Index Is Not A Bot! " ) ; // don't accidentally disconnect a human player.
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
botUser - > isBot = false ;
botUser - > lobbyUserID = lobbyUserID_t ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
FreeUser ( botUser ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserIsBot
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : GetLobbyUserIsBot ( lobbyUserID_t lobbyUserID ) const
{
2012-11-26 18:58:24 +00:00
const int index = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
const lobbyUser_t * botLobbyUser = GetLobbyUser ( index ) ;
if ( botLobbyUser = = NULL )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return botLobbyUser - > isBot ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : AddUsersFromMsg
Called on peer and host .
Simply parses a msg , and adds any new users from it to our own user list .
If we are the host , we will forward this to all peers except the peer that we just received it from .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : AddUsersFromMsg ( idBitMsg & msg , int fromPeer )
{
2012-11-26 18:58:24 +00:00
int userStart = GetNumLobbyUsers ( ) ;
int numNewUsers = msg . ReadByte ( ) ;
assert ( lobbyBackend ! = NULL ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Add the new users to our own list
2012-11-28 15:47:07 +00:00
for ( int u = 0 ; u < numNewUsers ; u + + )
{
2012-11-26 18:58:24 +00:00
lobbyUser_t newUser ;
// Read in the new user
newUser . ReadFromMsg ( msg ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Initialize their peerIndex and userID if we are the host
// (we'll send these back to them in the initial connect)
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
if ( fromPeer ! = - 1 ) // -1 means this is the host adding his own users, and this stuff is already computed
{
2012-11-26 18:58:24 +00:00
// local users will already have this information filled out.
2012-11-28 15:47:07 +00:00
newUser . address = peers [ fromPeer ] . address ;
2012-11-26 18:58:24 +00:00
newUser . peerIndex = fromPeer ;
2012-11-28 15:47:07 +00:00
if ( lobbyType = = TYPE_PARTY )
{
2012-11-26 18:58:24 +00:00
newUser . partyToken = GetPartyTokenAsHost ( ) ;
}
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
assert ( fromPeer = = host ) ;
// The host sends us all user addresses, except his local users, so we compute that here
2012-11-28 15:47:07 +00:00
if ( newUser . peerIndex = = - 1 )
{
newUser . address = peers [ fromPeer ] . address ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " NET: %s joined (%s) [partyToken = %08x]. \n " , newUser . gamertag , GetLobbyName ( ) , newUser . partyToken ) ;
2012-11-28 15:47:07 +00:00
lobbyUser_t * appendedUser = NULL ;
2012-11-26 18:58:24 +00:00
// First, try to replace a disconnected user
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; i + + )
{
lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
userStart = i ;
* user = newUser ;
appendedUser = user ;
break ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Add them to our list
2012-11-28 15:47:07 +00:00
if ( appendedUser = = NULL )
{
2012-11-26 18:58:24 +00:00
appendedUser = AllocUser ( newUser ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Run platform-specific handler after adding
assert ( appendedUser - > peerIndex = = newUser . peerIndex ) ; // paranoia
assert ( appendedUser - > lobbyUserID = = newUser . lobbyUserID ) ; // paranoia
RegisterUser ( appendedUser ) ;
}
// Forward list of the new users to all other peers
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
SendNewUsersToPeers ( fromPeer , userStart , numNewUsers ) ;
// Set the lobbies skill level
lobbyBackend - > UpdateLobbySkill ( GetAverageSessionLevel ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " ---------------- %s -------------------- \n " , GetLobbyName ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( int userIndex = 0 ; userIndex < GetNumLobbyUsers ( ) ; + + userIndex )
{
lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " party %08x user %s \n " , user - > partyToken , user - > gamertag ) ;
}
idLib : : Printf ( " ---------------- %s -------------------- \n " , GetLobbyName ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : UpdateSessionUserOnPeers
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : UpdateSessionUserOnPeers ( idBitMsg & msg )
{
for ( int p = 0 ; p < peers . Num ( ) ; p + + )
{
2012-11-26 18:58:24 +00:00
QueueReliableMessage ( p , RELIABLE_UPDATE_SESSION_USER , msg . GetReadData ( ) + msg . GetReadCount ( ) , msg . GetSize ( ) - msg . GetReadCount ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
HandleUpdateSessionUser ( msg ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : HandleHeadsetStateChange
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : HandleHeadsetStateChange ( int fromPeer , idBitMsg & msg )
{
2012-11-26 18:58:24 +00:00
int userCount = msg . ReadLong ( ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < userCount ; + + i )
{
2012-11-26 18:58:24 +00:00
lobbyUserID_t lobbyUserID ;
lobbyUserID . ReadFromMsg ( msg ) ;
bool state = msg . ReadBool ( ) ;
int talkerIndex = sessionCB - > GetVoiceChat ( ) - > FindTalkerByUserId ( lobbyUserID , lobbyType ) ;
sessionCB - > GetVoiceChat ( ) - > SetHeadsetState ( talkerIndex , state ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " User %d headset status: %d \n " , talkerIndex , state ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// If we are the host, let the other clients know about the headset state of this peer
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
// We should not be receiving a message with a user count > 1 if we are the host
assert ( userCount = = 1 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_MSG_SIZE ] ;
idBitMsg outMsg ( buffer , sizeof ( buffer ) ) ;
outMsg . WriteLong ( 1 ) ;
lobbyUserID . WriteToMsg ( outMsg ) ;
outMsg . WriteBool ( state ) ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < peers . Num ( ) ; + + j )
{
2012-11-26 18:58:24 +00:00
// Don't send this to the player that we just received the message from
2012-11-28 15:47:07 +00:00
if ( ! peers [ j ] . IsConnected ( ) | | j = = fromPeer )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
QueueReliableMessage ( j , RELIABLE_HEADSET_STATE , outMsg . GetReadData ( ) , outMsg . GetSize ( ) ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : HandleUpdateSessionUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : HandleUpdateSessionUser ( idBitMsg & msg )
{
2012-11-26 18:58:24 +00:00
// FIXME: Use a user id here
int sessionUserIndex = msg . ReadByte ( ) ;
2012-11-28 15:47:07 +00:00
lobbyUser_t * user = GetLobbyUser ( sessionUserIndex ) ;
if ( verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
user - > ReadClientMutableData ( msg ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : CreateUserUpdateMessage
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : CreateUserUpdateMessage ( int userIndex , idBitMsg & msg )
{
lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
msg . WriteByte ( userIndex ) ;
user - > WriteClientMutableData ( msg ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : UpdateLocalSessionUsers
2012-11-28 15:47:07 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
*/
2012-11-28 15:47:07 +00:00
void idLobby : : UpdateLocalSessionUsers ( )
{
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; i + + )
{
idLocalUser * localUser = GetLocalUserFromLobbyUserIndex ( i ) ;
lobbyUser_t * lobbyUser = GetLobbyUser ( i ) ;
if ( localUser = = NULL | | lobbyUser = = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( ! lobbyUser - > UpdateClientMutableData ( localUser ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE - 2 ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
CreateUserUpdateMessage ( i , msg ) ;
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
UpdateSessionUserOnPeers ( msg ) ;
2012-11-28 15:47:07 +00:00
}
else if ( IsPeer ( ) )
{
2012-11-26 18:58:24 +00:00
QueueReliableMessage ( host , RELIABLE_SESSION_USER_MODIFIED , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : PeerIndexForSessionUserIndex
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idLobby : : PeerIndexForSessionUserIndex ( int sessionUserIndex ) const
{
const lobbyUser_t * user = GetLobbyUser ( sessionUserIndex ) ;
if ( ! verify ( user ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
return - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return user - > peerIndex ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : HandleUserConnectFailure
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : HandleUserConnectFailure ( int p , idBitMsg & inMsg , int reliableType )
{
2012-11-26 18:58:24 +00:00
// Read user to get handle so we can send it back
inMsg . ReadByte ( ) ; // Num users
lobbyUser_t user ;
user . ReadFromMsg ( inMsg ) ;
// Not enough room, send failure ack
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
user . lobbyUserID . GetLocalUserHandle ( ) . WriteToMsg ( msg ) ; // Let peer know which user failed to connect
// Send it
QueueReliableMessage ( p , reliableType , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : ProcessUserDisconnectMsg
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : ProcessUserDisconnectMsg ( idBitMsg & msg )
{
2012-11-26 18:58:24 +00:00
idList < lobbyUserID_t > removeList ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Convert the msg into a list of id's
const int numUsers = msg . ReadByte ( ) ;
2012-11-28 15:47:07 +00:00
for ( int u = 0 ; u < numUsers ; u + + )
{
2012-11-26 18:58:24 +00:00
lobbyUserID_t lobbyUserID ;
lobbyUserID . ReadFromMsg ( msg ) ;
removeList . Append ( lobbyUserID ) ;
}
RemoveSessionUsersByIDList ( removeList ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : CompactDisconnectedUsers
Pack the user list by removing disconnected users
We need to do this , since when in a game , we aren ' t allowed to remove users from the game session .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : CompactDisconnectedUsers ( )
{
for ( int i = GetNumLobbyUsers ( ) - 1 ; i > = 0 ; i - - )
{
lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
FreeUser ( user ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RequestLocalUserJoin
Sends a request to the host to join a local user to a session .
If we are the host , we will do it immediately .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RequestLocalUserJoin ( idLocalUser * localUser )
{
2012-11-26 18:58:24 +00:00
assert ( IsRunningAsHostOrPeer ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Construct a msg that contains the user connect request
lobbyUser_t lobbyUser = CreateLobbyUserFromLocalUser ( localUser ) ;
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
msg . WriteByte ( 1 ) ; // 1 user
lobbyUser . WriteToMsg ( msg ) ; // Write user
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
AddUsersFromMsg ( msg , - 1 ) ;
localUser - > SetJoiningLobby ( lobbyType , false ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// Send request to host to add user
QueueReliableMessage ( host , RELIABLE_USER_CONNECT_REQUEST , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : RequestSessionUserDisconnect
Sends a request to the host to remove a session user from the session .
If we are the host , we will do it immediately .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : RequestSessionUserDisconnect ( int sessionUserIndex )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( ! IsRunningAsHostOrPeer ( ) )
{
2012-11-26 18:58:24 +00:00
// If we are not in an actual running session, just remove it.
// This is so we accurately reflect the local user list through the session users in the menus, etc.
// FIXME:
// This is a total hack, and we should really look at better separation of local users/session users
2012-11-28 15:47:07 +00:00
// and not rely on session users while in the menus.
2012-11-26 18:58:24 +00:00
FreeUser ( GetLobbyUser ( sessionUserIndex ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
lobbyUser_t * lobbyUser = GetLobbyUser ( sessionUserIndex ) ;
if ( ! verify ( lobbyUser ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( lobbyUser - > disconnecting = = true )
{
2012-11-26 18:58:24 +00:00
return ; // Already disconnecting
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
msg . WriteByte ( 1 ) ; // 1 user
lobbyUser - > lobbyUserID . WriteToMsg ( msg ) ;
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
idBitMsg readMsg ;
readMsg . InitRead ( msg . GetReadData ( ) , msg . GetSize ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// As the host, just disconnect immediately (we'll still send the notification to all peers though)
ProcessUserDisconnectMsg ( readMsg ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// Send the message
QueueReliableMessage ( host , RELIABLE_USER_DISCONNECT_REQUEST , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
// Mark user as disconnecting to make sure we don't keep sending the request
lobbyUser - > disconnecting = true ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : SyncLobbyUsersWithLocalUsers
This function will simply try and keep session [ lobbyType ] . users sync ' d up with local users .
As local users come and go , this function will detect that , and send msg ' s to the host that will
add / remove the users from the session .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : SyncLobbyUsersWithLocalUsers ( bool allowLocalJoins , bool onlineMatch )
{
if ( lobbyBackend = = NULL )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! IsRunningAsHostOrPeer ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( allowLocalJoins )
{
2012-11-26 18:58:24 +00:00
// If we are allowed to do so, allow local users to join the session user list
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < sessionCB - > GetSignInManager ( ) . GetNumLocalUsers ( ) ; i + + )
{
idLocalUser * localUser = sessionCB - > GetSignInManager ( ) . GetLocalUserByIndex ( i ) ;
if ( GetSessionUserFromLocalUser ( localUser ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
continue ; // Already in the lobby
}
2012-11-28 15:47:07 +00:00
if ( localUser - > IsJoiningLobby ( lobbyType ) )
{
2012-11-26 18:58:24 +00:00
continue ; // Already joining lobby if this type
}
2012-11-28 15:47:07 +00:00
if ( onlineMatch & & ! localUser - > CanPlayOnline ( ) )
{
2012-11-26 18:58:24 +00:00
continue ; // Not allowed to join this type of lobby
}
localUser - > SetJoiningLobby ( lobbyType , true ) ; // We'll reset this when we get the ack for this request
RequestLocalUserJoin ( localUser ) ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Find session users that are no longer allowed to be in the list
2012-11-28 15:47:07 +00:00
for ( int i = GetNumLobbyUsers ( ) - 1 ; i > = 0 ; i - - )
{
if ( ! IsSessionUserIndexLocal ( i ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
lobbyUser_t * lobbyUser = GetLobbyUser ( i ) ;
if ( lobbyUser ! = NULL & & lobbyUser - > isBot )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
idLocalUser * localUser = GetLocalUserFromLobbyUserIndex ( i ) ;
if ( localUser = = NULL | | ( onlineMatch & & ! localUser - > CanPlayOnline ( ) ) )
{
2012-11-26 18:58:24 +00:00
// Either the session user is no longer in the local user list,
// or not allowed to join online lobbies.
RequestSessionUserDisconnect ( i ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
localUser - > SetJoiningLobby ( lobbyType , false ) ; // Remove joining lobby flag if we are in the lobby
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : IsLobbyUserDisconnected
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : IsLobbyUserDisconnected ( int userIndex ) const
{
const lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( user = = NULL )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
if ( user - > isBot )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : IsLobbyUserValid
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : IsLobbyUserValid ( lobbyUserID_t lobbyUserID ) const
{
if ( ! lobbyUserID . IsValid ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( GetLobbyUserIndexByID ( lobbyUserID ) = = - 1 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : ValidateConnectedUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : ValidateConnectedUser ( const lobbyUser_t * user ) const
{
if ( user = = NULL )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = - 1 )
{
2012-11-26 18:58:24 +00:00
return true ; // Host
}
2012-11-28 15:47:07 +00:00
if ( IsHost ( ) )
{
if ( user - > peerIndex < 0 | | user - > peerIndex > = peers . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! peers [ user - > peerIndex ] . IsConnected ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : IsLobbyUserLoaded
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : IsLobbyUserLoaded ( lobbyUserID_t lobbyUserID ) const
{
2012-11-26 18:58:24 +00:00
assert ( lobbyType = = GetActingGameStateLobbyType ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int userIndex = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
if ( ! verify ( userIndex ! = - 1 ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
const lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( user = = NULL )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( user - > isBot )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
if ( ! ValidateConnectedUser ( user ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( IsSessionUserLocal ( user ) )
{
2012-11-26 18:58:24 +00:00
return loaded ; // If this is a local user, check the local loaded flag
}
2012-11-28 15:47:07 +00:00
if ( ! verify ( user - > peerIndex > = 0 & & user - > peerIndex < peers . Num ( ) ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return peers [ user - > peerIndex ] . loaded ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : LobbyUserHasFirstFullSnap
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idLobby : : LobbyUserHasFirstFullSnap ( lobbyUserID_t lobbyUserID ) const
{
2012-11-26 18:58:24 +00:00
assert ( lobbyType = = GetActingGameStateLobbyType ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int userIndex = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
const lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( ! ValidateConnectedUser ( user ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = - 1 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( peers [ user - > peerIndex ] . snapProc - > GetFullSnapBaseSequence ( ) < idSnapshotProcessor : : INITIAL_SNAP_SEQUENCE )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserIdByOrdinal
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
lobbyUserID_t idLobby : : GetLobbyUserIdByOrdinal ( int userIndex ) const
{
const lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( user = = NULL )
{
2012-11-26 18:58:24 +00:00
return lobbyUserID_t ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( user - > isBot )
{
2012-11-26 18:58:24 +00:00
return user - > lobbyUserID ;
}
2012-11-28 15:47:07 +00:00
if ( ! ValidateConnectedUser ( user ) )
{
2012-11-26 18:58:24 +00:00
return lobbyUserID_t ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return user - > lobbyUserID ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetLobbyUserIndexFromLobbyUserID
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idLobby : : GetLobbyUserIndexFromLobbyUserID ( lobbyUserID_t lobbyUserID ) const
{
2012-11-26 18:58:24 +00:00
return GetLobbyUserIndexByID ( lobbyUserID ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : EnableSnapshotsForLobbyUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : EnableSnapshotsForLobbyUser ( lobbyUserID_t lobbyUserID )
{
2012-11-26 18:58:24 +00:00
assert ( lobbyType = = GetActingGameStateLobbyType ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int userIndex = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
const lobbyUser_t * user = GetLobbyUser ( userIndex ) ;
if ( ! ValidateConnectedUser ( user ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex = = - 1 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
peers [ user - > peerIndex ] . pauseSnapshots = false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetAverageSessionLevel
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idLobby : : GetAverageSessionLevel ( )
{
2012-11-26 18:58:24 +00:00
float level = 0.0f ;
int numActiveMembers = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; i + + )
{
const lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
level + = user - > level ;
numActiveMembers + + ;
}
2012-11-28 15:47:07 +00:00
if ( numActiveMembers > 0 )
{
level / = ( float ) numActiveMembers ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float ret = Max ( level , 1.0f ) ;
NET_VERBOSE_PRINT ( " NET: GetAverageSessionLevel %g \n " , ret ) ;
return ret ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetAverageLocalUserLevel
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idLobby : : GetAverageLocalUserLevel ( bool onlineOnly )
{
2012-11-26 18:58:24 +00:00
float level = 0.0f ;
int numActiveMembers = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < sessionCB - > GetSignInManager ( ) . GetNumLocalUsers ( ) ; + + i )
{
const idLocalUser * localUser = sessionCB - > GetSignInManager ( ) . GetLocalUserByIndex ( i ) ;
if ( onlineOnly & & ! localUser - > CanPlayOnline ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
const idPlayerProfile * profile = localUser - > GetProfile ( ) ;
if ( profile = = NULL )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
level + = profile - > GetLevel ( ) ;
numActiveMembers + + ;
}
2012-11-28 15:47:07 +00:00
if ( numActiveMembers > 0 )
{
level / = ( float ) numActiveMembers ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return Max ( level , 1.0f ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : QueueReliablePlayerToPlayerMessage
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : QueueReliablePlayerToPlayerMessage ( int fromSessionUserIndex , int toSessionUserIndex , reliablePlayerToPlayer_t type , const byte * data , int dataLen )
{
2012-11-26 18:58:24 +00:00
reliablePlayerToPlayerHeader_t info ;
info . fromSessionUserIndex = fromSessionUserIndex ;
info . toSessionUserIndex = toSessionUserIndex ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Some kind of pool allocator for packet buffers would be nice.
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_PACKET_SIZE ] ;
idBitMsg outmsg ( buffer , sizeof ( buffer ) ) ;
2012-11-28 15:47:07 +00:00
if ( ! info . Write ( this , outmsg ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " NET: Can't queue invalid reliable player to player msg " ) ;
return ;
}
outmsg . WriteData ( data , dataLen ) ;
2012-11-28 15:47:07 +00:00
const lobbyUser_t * targetUser = GetLobbyUser ( toSessionUserIndex ) ;
if ( ! verify ( targetUser ! = NULL ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
const int sendToPeer = IsHost ( ) ? targetUser - > peerIndex : host ;
2012-11-28 15:47:07 +00:00
QueueReliableMessage ( sendToPeer , RELIABLE_PLAYER_TO_PLAYER_BEGIN + ( int ) type , outmsg . GetReadData ( ) , outmsg . GetSize ( ) ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : KickLobbyUser
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idLobby : : KickLobbyUser ( lobbyUserID_t lobbyUserID )
{
if ( ! IsHost ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
const int lobbyUserIndex = GetLobbyUserIndexByID ( lobbyUserID ) ;
2012-11-28 15:47:07 +00:00
lobbyUser_t * user = GetLobbyUser ( lobbyUserIndex ) ;
if ( user ! = NULL & & ! IsSessionUserLocal ( user ) )
{
2012-11-26 18:58:24 +00:00
// Send an explicit kick msg, so they know why they were removed
2012-11-28 15:47:07 +00:00
if ( user - > peerIndex > = 0 & & user - > peerIndex < peers . Num ( ) )
{
2012-11-26 18:58:24 +00:00
byte buffer [ idPacketProcessor : : MAX_MSG_SIZE ] ;
idBitMsg msg ( buffer , sizeof ( buffer ) ) ;
msg . WriteByte ( lobbyUserIndex ) ;
QueueReliableMessage ( user - > peerIndex , RELIABLE_KICK_PLAYER , msg . GetReadData ( ) , msg . GetSize ( ) ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idLobby : : GetNumConnectedUsers
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idLobby : : GetNumConnectedUsers ( ) const
{
2012-11-26 18:58:24 +00:00
int numConnectectUsers = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < GetNumLobbyUsers ( ) ; i + + )
{
const lobbyUser_t * user = GetLobbyUser ( i ) ;
if ( user - > IsDisconnected ( ) )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
numConnectectUsers + + ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return numConnectectUsers ;
}