void HandleFriendsList( IPacketMsg packetMsg )
{
var list = new ClientMsgProtobuf<CMsgClientFriendsList>( packetMsg );
cache.LocalUser.SteamID = this.Client.SteamID;
if ( !list.Body.bincremental )
{
// if we're not an incremental update, the message contains all friends, so we should clear our current list
lock ( listLock )
{
friendList.Clear();
clanList.Clear();
}
}
// we have to request information for all of our friends because steam only sends persona information for online friends
var reqInfo = new ClientMsgProtobuf<CMsgClientRequestFriendData>( EMsg.ClientRequestFriendData );
reqInfo.Body.persona_state_requested = ( uint )defaultInfoRequest;
lock ( listLock )
{
List<SteamID> friendsToRemove = new List<SteamID>();
List<SteamID> clansToRemove = new List<SteamID>();
foreach ( var friendObj in list.Body.friends )
{
SteamID friendId = friendObj.ulfriendid;
if ( friendId.IsIndividualAccount )
{
var user = cache.GetUser( friendId );
user.Relationship = ( EFriendRelationship )friendObj.efriendrelationship;
if ( friendList.Contains( friendId ) )
{
// if this is a friend on our list, and they removed us, mark them for removal
if ( user.Relationship == EFriendRelationship.None )
friendsToRemove.Add( friendId );
}
else
{
// we don't know about this friend yet, lets add them
friendList.Add( friendId );
}
}
else if ( friendId.IsClanAccount )
{
var clan = cache.Clans.GetAccount( friendId );
clan.Relationship = ( EClanRelationship )friendObj.efriendrelationship;
if ( clanList.Contains( friendId ) )
{
// mark clans we were removed/kicked from
// note: not actually sure about the kicked relationship, but i'm using it for good measure
if ( clan.Relationship == EClanRelationship.None || clan.Relationship == EClanRelationship.Kicked )
clansToRemove.Add( friendId );
}
else
{
// don't know about this clan, add it
clanList.Add( friendId );
}
}
if ( !list.Body.bincremental )
{
// request persona state for our friend & clan list when it's a non-incremental update
reqInfo.Body.friends.Add( friendId );
}
}
// remove anything we marked for removal
friendsToRemove.ForEach( f => friendList.Remove( f ) );
clansToRemove.ForEach( c => clanList.Remove( c ) );
}
if ( reqInfo.Body.friends.Count > 0 )
{
this.Client.Send( reqInfo );
}
#if STATIC_CALLBACKS
var callback = new FriendsListCallback( Client, list.Body );
SteamClient.PostCallback( callback );
#else
var callback = new FriendsListCallback( list.Body );
this.Client.PostCallback( callback );
#endif
}
void HandlePersonaState( IPacketMsg packetMsg )