< Summary

Class:FriendsController
Assembly:FriendsController
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/FriendsController/FriendsController.cs
Covered lines:25
Uncovered lines:67
Coverable lines:92
Total lines:288
Line coverage:27.1% (25 of 92)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
FriendsController()0%110100%
GetUserStatus(...)0%6200%
ContainsStatus(...)0%6200%
GetFriends()0%2100%
RejectFriendship(...)0%2100%
IsFriend(...)0%110100%
RemoveFriend(...)0%2100%
RequestFriendship(...)0%2100%
CancelRequest(...)0%2100%
AcceptFriendship(...)0%2100%
FriendNotFound(...)0%6200%
InitializeFriends(...)0%1561200%
UpdateUserStatus(...)0%12300%
UpdateUserPresence(...)0%6200%
UpdateFriendshipStatus(...)0%9.459082.35%
UpdateFriendshipStatus(...)0%2100%
ItsAnOutdatedUpdate(...)0%330100%
ToFriendshipStatus(...)0%19.948042.86%
FakeOnlineFriend()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/FriendsController/FriendsController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using UnityEngine;
 5
 6public class FriendsController : MonoBehaviour, IFriendsController
 7{
 8    public static bool VERBOSE = false;
 129    public static FriendsController i { get; private set; }
 10
 111    public int friendCount => friends.Count(f => f.Value.friendshipStatus == FriendshipStatus.FRIEND);
 12
 1813    void Awake() { i = this; }
 14
 15    private const bool KERNEL_CAN_REMOVE_ENTRIES = false;
 216    public bool isInitialized { get; private set; } = false;
 17
 18    public int ReceivedRequestCount =>
 119        friends.Values.Count(status => status.friendshipStatus == FriendshipStatus.REQUESTED_FROM);
 20
 921    public Dictionary<string, UserStatus> friends = new Dictionary<string, UserStatus>();
 22
 23    [System.Serializable]
 24    public class UserStatus
 25    {
 26        [System.Serializable]
 27        public class Realm
 28        {
 29            public string serverName;
 30            public string layer;
 31        }
 32
 33        public Realm realm;
 34        public Vector2 position;
 35        public string userId;
 36        public FriendshipStatus friendshipStatus;
 37        public PresenceStatus presence;
 38        [NonSerialized] public DateTime friendshipStartedTime;
 39    }
 40
 41    [System.Serializable]
 42    public class FriendshipInitializationMessage
 43    {
 44        public string[] currentFriends;
 45        public string[] requestedTo;
 46        public string[] requestedFrom;
 47    }
 48
 49    [System.Serializable]
 50    public class FriendshipUpdateStatusMessage
 51    {
 52        public string userId;
 53        public FriendshipAction action;
 54    }
 55
 56    public UserStatus GetUserStatus(string userId)
 57    {
 058        if (!friends.ContainsKey(userId))
 059            return new UserStatus() { userId = userId, friendshipStatus = FriendshipStatus.NOT_FRIEND };
 60
 061        return friends[userId];
 62    }
 63
 64    public bool ContainsStatus(string friendId, FriendshipStatus status)
 65    {
 066        if (!friends.ContainsKey(friendId)) return false;
 067        return friends[friendId].friendshipStatus == status;
 68    }
 69
 70    public event Action<string, UserStatus> OnUpdateUserStatus;
 71    public event Action<string, FriendshipAction> OnUpdateFriendship;
 72    public event Action<string> OnFriendNotFound;
 73    public event Action OnInitialized;
 74
 075    public Dictionary<string, UserStatus> GetFriends() { return new Dictionary<string, UserStatus>(friends); }
 76
 77    public void RejectFriendship(string friendUserId)
 78    {
 079        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 80        {
 81            userId = friendUserId,
 82            action = FriendshipAction.REJECTED
 83        });
 084    }
 85
 186    public bool IsFriend(string userId) => friends.ContainsKey(userId);
 87
 88    public void RemoveFriend(string friendId)
 89    {
 090        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 91        {
 92            action = FriendshipAction.DELETED,
 93            userId = friendId
 94        });
 095    }
 96
 97    public void RequestFriendship(string friendUserId)
 98    {
 099        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 100        {
 101            userId = friendUserId,
 102            action = FriendshipAction.REQUESTED_TO
 103        });
 0104    }
 105
 106    public void CancelRequest(string friendUserId)
 107    {
 0108        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 109        {
 110            userId = friendUserId,
 111            action = FriendshipAction.CANCELLED
 112        });
 0113    }
 114
 115    public void AcceptFriendship(string friendUserId)
 116    {
 0117        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 118        {
 119            userId = friendUserId,
 120            action = FriendshipAction.APPROVED
 121        });
 0122    }
 123
 0124    public void FriendNotFound(string name) { OnFriendNotFound?.Invoke(name); }
 125
 126    public void InitializeFriends(string json)
 127    {
 0128        isInitialized = true;
 129
 0130        FriendshipInitializationMessage msg = JsonUtility.FromJson<FriendshipInitializationMessage>(json);
 0131        HashSet<string> processedIds = new HashSet<string>();
 132
 0133        foreach (var userId in msg.currentFriends)
 134        {
 0135            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 136                { action = FriendshipAction.APPROVED, userId = userId });
 0137            if (!processedIds.Contains(userId))
 0138                processedIds.Add(userId);
 139        }
 140
 0141        foreach (var userId in msg.requestedFrom)
 142        {
 0143            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 144                { action = FriendshipAction.REQUESTED_FROM, userId = userId });
 0145            if (!processedIds.Contains(userId))
 0146                processedIds.Add(userId);
 147        }
 148
 0149        foreach (var userId in msg.requestedTo)
 150        {
 0151            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 152                { action = FriendshipAction.REQUESTED_TO, userId = userId });
 0153            if (!processedIds.Contains(userId))
 0154                processedIds.Add(userId);
 155        }
 156
 0157        Queue<string> newFriends = new Queue<string>();
 158
 0159        foreach (var kvp in friends)
 160        {
 0161            if (!processedIds.Contains(kvp.Key))
 162            {
 0163                newFriends.Enqueue(kvp.Key);
 164            }
 165        }
 166
 0167        while (newFriends.Count > 0)
 168        {
 0169            var userId = newFriends.Dequeue();
 170
 171            if (KERNEL_CAN_REMOVE_ENTRIES)
 172            {
 173                UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 174                    { action = FriendshipAction.NONE, userId = userId });
 175            }
 176
 0177            if (friends.ContainsKey(userId))
 0178                friends.Remove(userId);
 179        }
 180
 0181        OnInitialized?.Invoke();
 0182    }
 183
 184    public void UpdateUserStatus(UserStatus newUserStatus)
 185    {
 0186        if (!friends.ContainsKey(newUserStatus.userId))
 187        {
 0188            friends.Add(newUserStatus.userId, newUserStatus);
 0189        }
 190        else
 191        {
 0192            friends[newUserStatus.userId] = newUserStatus;
 193        }
 194
 0195        OnUpdateUserStatus?.Invoke(newUserStatus.userId, newUserStatus);
 0196    }
 197
 198    public void UpdateUserPresence(string json)
 199    {
 0200        UserStatus newUserStatus = JsonUtility.FromJson<UserStatus>(json);
 201
 0202        if (!friends.ContainsKey(newUserStatus.userId))
 0203            return;
 204
 205        // Kernel doesn't send the friendship status on this call, we have to keep it or it gets defaulted
 0206        newUserStatus.friendshipStatus = friends[newUserStatus.userId].friendshipStatus;
 207
 0208        UpdateUserStatus(newUserStatus);
 0209    }
 210
 211    public void UpdateFriendshipStatus(FriendshipUpdateStatusMessage msg)
 212    {
 6213        var friendshipStatus = ToFriendshipStatus(msg.action);
 6214        var userId = msg.userId;
 215
 6216        if (friends.ContainsKey(userId) && friends[userId].friendshipStatus == friendshipStatus)
 0217            return;
 218
 6219        if (!friends.ContainsKey(userId))
 2220            friends.Add(userId, new UserStatus());
 221
 6222        if (ItsAnOutdatedUpdate(userId, friendshipStatus))
 0223            return;
 224
 6225        friends[userId].friendshipStatus = friendshipStatus;
 226
 6227        if (friendshipStatus == FriendshipStatus.FRIEND)
 2228            friends[userId].friendshipStartedTime = DateTime.UtcNow;
 229
 6230        if (VERBOSE)
 0231            Debug.Log($"Change friend status of {userId} to {friends[userId].friendshipStatus}");
 232
 6233        if (friendshipStatus == FriendshipStatus.NOT_FRIEND)
 2234            friends.Remove(userId);
 235
 6236        OnUpdateFriendship?.Invoke(userId, msg.action);
 6237    }
 238
 239    public void UpdateFriendshipStatus(string json)
 240    {
 0241        FriendshipUpdateStatusMessage msg = JsonUtility.FromJson<FriendshipUpdateStatusMessage>(json);
 0242        UpdateFriendshipStatus(msg);
 0243    }
 244
 245    private bool ItsAnOutdatedUpdate(string userId, FriendshipStatus friendshipStatus)
 246    {
 6247        return friendshipStatus == FriendshipStatus.REQUESTED_FROM
 248               && friends[userId].friendshipStatus == FriendshipStatus.FRIEND
 249               && (DateTime.UtcNow - friends[userId].friendshipStartedTime).TotalSeconds < 5;
 250    }
 251
 252    private static FriendshipStatus ToFriendshipStatus(FriendshipAction action)
 253    {
 254        switch (action)
 255        {
 256            case FriendshipAction.NONE:
 257                break;
 258            case FriendshipAction.APPROVED:
 2259                return FriendshipStatus.FRIEND;
 260            case FriendshipAction.REJECTED:
 0261                return FriendshipStatus.NOT_FRIEND;
 262            case FriendshipAction.CANCELLED:
 0263                return FriendshipStatus.NOT_FRIEND;
 264            case FriendshipAction.REQUESTED_FROM:
 0265                return FriendshipStatus.REQUESTED_FROM;
 266            case FriendshipAction.REQUESTED_TO:
 2267                return FriendshipStatus.REQUESTED_TO;
 268            case FriendshipAction.DELETED:
 2269                return FriendshipStatus.NOT_FRIEND;
 270        }
 271
 0272        return FriendshipStatus.NOT_FRIEND;
 273    }
 274
 275    [ContextMenu("Change user stats to online")]
 276    public void FakeOnlineFriend()
 277    {
 0278        var friend = friends.Values.First();
 0279        UpdateUserStatus(new UserStatus
 280        {
 281            userId = friend.userId,
 282            position = friend.position,
 283            presence = PresenceStatus.ONLINE,
 284            friendshipStatus = friend.friendshipStatus,
 285            friendshipStartedTime = friend.friendshipStartedTime
 286        });
 0287    }
 288}