예제 #1
0
        internal async Task UpdateList(CMsgClientFriendsList list)
        {
            await _slim.WaitAsync();

            var users = new List <(IUser Before, IUser After)>();
            var clans = new List <(IClan Before, IClan After)>();

            try
            {
                if (list.max_friend_countSpecified)
                {
                    _maxFriendsCount = list.max_friend_count;
                }

                if (!list.bincremental)
                {
                    _users.Clear();
                    _clans.Clear();
                }

                foreach (var friend in list.friends)
                {
                    SteamId friendId = friend.ulfriendid;

                    if (friendId.IsIndividualAccount)
                    {
                        IUser before;
                        IUser after;

                        var relationship = (FriendRelationship)friend.efriendrelationship;
                        if (_users.TryGetValue(friendId, out var user)) // if we have a user already
                        {
                            before = user;

                            if (relationship == FriendRelationship.None) // and the new relationship is "None"
                            {
                                _users.Remove(friendId);                 // remove them and tell everyone they don't exist anymore

                                after = null;
                            }
                            else // otherwise...
                            {
                                if (user is UnknownUser) // if they were previously unknown
                                {
                                    after = new UnknownUser(user.Id, relationship); // make the after user just another unknown user
                                }
                                else
                                {
                                    User realUser = (User)user;                      // otherwise
                                    after = realUser.WithRelationship(relationship); // clone the existing one and add a relationship
                                }
                            }
                        }
                        else // or unless we don't have that user
                        {
                            before = null;
                            after  = new UnknownUser(friendId, relationship); // make a new unknown one and tell everyone that person now exists

                            _users[friendId] = after;
                        }

                        users.Add((before, after)); // tell everyone we're bffs or whatever
                    }
                    else if (friendId.IsClan)
                    {
                        IClan before;
                        IClan after;

                        var relationship = (ClanRelationship)friend.efriendrelationship;
                        if (_clans.TryGetValue(friendId, out var clan))
                        {
                            before = clan;

                            if (relationship == ClanRelationship.None)
                            {
                                _users.Remove(friendId);

                                after = null;
                            }
                            else
                            {
                                if (clan is UnknownClan)
                                {
                                    after = new UnknownClan(clan.Id, relationship);
                                }
                                else
                                {
                                    Clan realClan = (Clan)clan;
                                    after = realClan.WithRelationship(relationship);
                                }
                            }
                        }
                        else
                        {
                            before = null;
                            after  = new UnknownClan(friendId, relationship);

                            _clans[friendId] = after;
                        }

                        clans.Add((before, after));
                    }
                }
            }
            finally
            {
                _slim.Release();
            }

            // send update notifications outside the lock so other threads can update if possible
            await Task.WhenAll(users.Select(t => InvokeUserUpdated(t.Before, t.After)).Concat(clans.Select(t => InvokeClanUpdated(t.Before, t.After)))).ConfigureAwait(false);
        }
예제 #2
0
        internal async Task UpdateFriend(CMsgClientPersonaState persona)
        {
            var users = new List <(IUser Before, IUser After)>();
            var clans = new List <(IClan Before, IClan After)>();

            ISelfUser currentBefore = null;
            ISelfUser currentAfter  = null;

            await _slim.WaitAsync();

            try
            {
                var flag = (ClientPersonaStateFlag)persona.status_flags;

                foreach (var friend in persona.friends)
                {
                    SteamId friendId = friend.friendid;

                    if (friendId == Client.SteamId) // that's us!
                    {
                        currentBefore = _currentUser;

                        if (currentBefore is OfflineSelfUser)
                        {
                            currentAfter = SelfUser.Create(Client, friend, flag);
                        }
                        else
                        {
                            currentAfter = (currentBefore as SelfUser).WithState(friend, flag);
                        }
                    }
                    else if (friendId.IsClan)
                    {
                        IClan before;
                        IClan after;

                        before = _clans[friend.friendid];

                        if (before is UnknownUser)
                        {
                            after = Clan.Create(Client, before.Relationship, friend, flag);
                        }
                        else
                        {
                            after = (before as Clan).WithPersonaState(friend, flag);
                        }

                        _clans[after.Id] = after;

                        clans.Add((before, after));
                    }
                    else
                    {
                        IUser before;
                        IUser after;

                        before = _users[friend.friendid];

                        if (before is UnknownUser)
                        {
                            after = User.Create(Client, before.Relationship, friend, flag);
                        }
                        else
                        {
                            after = (before as User).WithState(friend, flag);
                        }

                        _users[after.Id] = after;

                        users.Add((before, after));
                    }
                }
            }
            finally
            {
                _slim.Release();
            }

            if (currentBefore != null || currentAfter != null)
            {
                _currentUser = currentAfter;
                await InvokeCurrentUserUpdated(currentBefore, currentAfter).ConfigureAwait(false);
            }

            await Task.WhenAll(users.Select(t => InvokeUserUpdated(t.Before, t.After)).Concat(clans.Select(t => InvokeClanUpdated(t.Before, t.After)))).ConfigureAwait(false);
        }