< Summary

Class:FriendsController
Assembly:FriendsController
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/FriendsController/FriendsController.cs
Covered lines:26
Uncovered lines:57
Coverable lines:83
Total lines:253
Line coverage:31.3% (26 of 83)
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%2.152066.67%
GetFriends()0%110100%
RejectFriendship(...)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%

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;
 917    public Dictionary<string, UserStatus> friends = new Dictionary<string, UserStatus>();
 18
 19    [System.Serializable]
 20    public class UserStatus
 21    {
 22        [System.Serializable]
 23        public class Realm
 24        {
 25            public string serverName;
 26            public string layer;
 27        }
 28
 29        public Realm realm;
 30        public Vector2 position;
 31        public string userId;
 32        public FriendshipStatus friendshipStatus;
 33        public PresenceStatus presence;
 34        [NonSerialized] public DateTime friendshipStartedTime;
 35    }
 36
 37    [System.Serializable]
 38    public class FriendshipInitializationMessage
 39    {
 40        public string[] currentFriends;
 41        public string[] requestedTo;
 42        public string[] requestedFrom;
 43    }
 44
 45    [System.Serializable]
 46    public class FriendshipUpdateStatusMessage
 47    {
 48        public string userId;
 49        public FriendshipAction action;
 50    }
 51
 52    public UserStatus GetUserStatus(string userId)
 53    {
 154        if (!friends.ContainsKey(userId))
 155            return new UserStatus() { userId = userId, friendshipStatus = FriendshipStatus.NOT_FRIEND };
 56
 057        return friends[userId];
 58    }
 59
 60    public event Action<string, UserStatus> OnUpdateUserStatus;
 61    public event Action<string, FriendshipAction> OnUpdateFriendship;
 62    public event Action<string> OnFriendNotFound;
 63    public event Action OnInitialized;
 64
 765    public Dictionary<string, UserStatus> GetFriends() { return new Dictionary<string, UserStatus>(friends); }
 66
 67    public void RejectFriendship(string friendUserId)
 68    {
 069        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 70        {
 71            userId = friendUserId,
 72            action = FriendshipAction.REJECTED
 73        });
 074    }
 75
 76    public void RequestFriendship(string friendUserId)
 77    {
 078        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 79        {
 80            userId = friendUserId,
 81            action = FriendshipAction.REQUESTED_TO
 82        });
 083    }
 84
 85    public void CancelRequest(string friendUserId)
 86    {
 087        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 88        {
 89            userId = friendUserId,
 90            action = FriendshipAction.CANCELLED
 91        });
 092    }
 93
 94    public void AcceptFriendship(string friendUserId)
 95    {
 096        UpdateFriendshipStatus(new FriendshipUpdateStatusMessage
 97        {
 98            userId = friendUserId,
 99            action = FriendshipAction.APPROVED
 100        });
 0101    }
 102
 0103    public void FriendNotFound(string name) { OnFriendNotFound?.Invoke(name); }
 104
 105    public void InitializeFriends(string json)
 106    {
 0107        isInitialized = true;
 108
 0109        FriendshipInitializationMessage msg = JsonUtility.FromJson<FriendshipInitializationMessage>(json);
 0110        HashSet<string> processedIds = new HashSet<string>();
 111
 0112        foreach (var userId in msg.currentFriends)
 113        {
 0114            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 115                { action = FriendshipAction.APPROVED, userId = userId });
 0116            if (!processedIds.Contains(userId))
 0117                processedIds.Add(userId);
 118        }
 119
 0120        foreach (var userId in msg.requestedFrom)
 121        {
 0122            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 123                { action = FriendshipAction.REQUESTED_FROM, userId = userId });
 0124            if (!processedIds.Contains(userId))
 0125                processedIds.Add(userId);
 126        }
 127
 0128        foreach (var userId in msg.requestedTo)
 129        {
 0130            UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 131                { action = FriendshipAction.REQUESTED_TO, userId = userId });
 0132            if (!processedIds.Contains(userId))
 0133                processedIds.Add(userId);
 134        }
 135
 0136        Queue<string> newFriends = new Queue<string>();
 137
 0138        foreach (var kvp in friends)
 139        {
 0140            if (!processedIds.Contains(kvp.Key))
 141            {
 0142                newFriends.Enqueue(kvp.Key);
 143            }
 144        }
 145
 0146        while (newFriends.Count > 0)
 147        {
 0148            var userId = newFriends.Dequeue();
 149
 150            if (KERNEL_CAN_REMOVE_ENTRIES)
 151            {
 152                UpdateFriendshipStatus(new FriendshipUpdateStatusMessage()
 153                    { action = FriendshipAction.NONE, userId = userId });
 154            }
 155
 0156            if (friends.ContainsKey(userId))
 0157                friends.Remove(userId);
 158        }
 159
 0160        OnInitialized?.Invoke();
 0161    }
 162
 163    public void UpdateUserStatus(UserStatus newUserStatus)
 164    {
 0165        if (!friends.ContainsKey(newUserStatus.userId))
 166        {
 0167            friends.Add(newUserStatus.userId, newUserStatus);
 0168        }
 169        else
 170        {
 0171            friends[newUserStatus.userId] = newUserStatus;
 172        }
 173
 0174        OnUpdateUserStatus?.Invoke(newUserStatus.userId, newUserStatus);
 0175    }
 176
 177    public void UpdateUserPresence(string json)
 178    {
 0179        UserStatus newUserStatus = JsonUtility.FromJson<UserStatus>(json);
 180
 0181        if (!friends.ContainsKey(newUserStatus.userId))
 0182            return;
 183
 184        // Kernel doesn't send the friendship status on this call, we have to keep it or it gets defaulted
 0185        newUserStatus.friendshipStatus = friends[newUserStatus.userId].friendshipStatus;
 186
 0187        UpdateUserStatus(newUserStatus);
 0188    }
 189
 190    public void UpdateFriendshipStatus(FriendshipUpdateStatusMessage msg)
 191    {
 6192        var friendshipStatus = ToFriendshipStatus(msg.action);
 6193        var userId = msg.userId;
 194
 6195        if (friends.ContainsKey(userId) && friends[userId].friendshipStatus == friendshipStatus)
 0196            return;
 197
 6198        if (!friends.ContainsKey(userId))
 2199            friends.Add(userId, new UserStatus());
 200
 6201        if (ItsAnOutdatedUpdate(userId, friendshipStatus))
 0202            return;
 203
 6204        friends[userId].friendshipStatus = friendshipStatus;
 205
 6206        if (friendshipStatus == FriendshipStatus.FRIEND)
 2207            friends[userId].friendshipStartedTime = DateTime.UtcNow;
 208
 6209        if (VERBOSE)
 0210            Debug.Log($"Change friend status of {userId} to {friends[userId].friendshipStatus}");
 211
 6212        if (friendshipStatus == FriendshipStatus.NOT_FRIEND)
 2213            friends.Remove(userId);
 214
 6215        OnUpdateFriendship?.Invoke(userId, msg.action);
 6216    }
 217
 218    public void UpdateFriendshipStatus(string json)
 219    {
 0220        FriendshipUpdateStatusMessage msg = JsonUtility.FromJson<FriendshipUpdateStatusMessage>(json);
 0221        UpdateFriendshipStatus(msg);
 0222    }
 223
 224    private bool ItsAnOutdatedUpdate(string userId, FriendshipStatus friendshipStatus)
 225    {
 6226        return friendshipStatus == FriendshipStatus.REQUESTED_FROM
 227               && friends[userId].friendshipStatus == FriendshipStatus.FRIEND
 228               && (DateTime.UtcNow - friends[userId].friendshipStartedTime).TotalSeconds < 5;
 229    }
 230
 231    private static FriendshipStatus ToFriendshipStatus(FriendshipAction action)
 232    {
 233        switch (action)
 234        {
 235            case FriendshipAction.NONE:
 236                break;
 237            case FriendshipAction.APPROVED:
 2238                return FriendshipStatus.FRIEND;
 239            case FriendshipAction.REJECTED:
 0240                return FriendshipStatus.NOT_FRIEND;
 241            case FriendshipAction.CANCELLED:
 0242                return FriendshipStatus.NOT_FRIEND;
 243            case FriendshipAction.REQUESTED_FROM:
 0244                return FriendshipStatus.REQUESTED_FROM;
 245            case FriendshipAction.REQUESTED_TO:
 2246                return FriendshipStatus.REQUESTED_TO;
 247            case FriendshipAction.DELETED:
 2248                return FriendshipStatus.NOT_FRIEND;
 249        }
 250
 0251        return FriendshipStatus.NOT_FRIEND;
 252    }
 253}