< Summary

Class:WebSocketCommunication
Assembly:WebSocketCommunication
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/KernelCommunication/WebSocketCommunication/WebSocketCommunication.cs
Covered lines:109
Uncovered lines:32
Coverable lines:141
Total lines:230
Line coverage:77.3% (109 of 141)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WebSocketCommunication()0%110100%
WebSocketCommunication()0%110100%
StartServer(...)0%5.674052.94%
InitMessageTypeToBridgeName()0%110100%
ProcessMessages()0%164.0218023.33%
Dispose()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/KernelCommunication/WebSocketCommunication/WebSocketCommunication.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Net.Sockets;
 5using DCL;
 6using UnityEngine;
 7using WebSocketSharp.Server;
 8
 9public class WebSocketCommunication : IKernelCommunication
 10{
 11    WebSocketServer ws;
 12    private Coroutine updateCoroutine;
 13    private bool requestStop = false;
 14
 12315    private Dictionary<string, GameObject> bridgeGameObjects = new Dictionary<string, GameObject>();
 16
 12317    public Dictionary<string, string> messageTypeToBridgeName = new Dictionary<string, string>(); // Public to be able t
 18
 19    [System.NonSerialized]
 120    public static Queue<DCLWebSocketService.Message> queuedMessages = new Queue<DCLWebSocketService.Message>();
 21
 22    [System.NonSerialized]
 23    public static volatile bool queuedMessagesDirty;
 24
 025    public bool isServerReady => ws.IsListening;
 26
 27    private string StartServer(int port, int maxPort)
 28    {
 12329        if (port > maxPort)
 30        {
 031            throw new SocketException((int)SocketError.AddressAlreadyInUse);
 32        }
 12333        string wssServerUrl = $"ws://localhost:{port}/";
 12334        string wssServiceId = "dcl";
 12335        string wssUrl = wssServerUrl + wssServiceId;
 36        try
 37        {
 12338            ws = new WebSocketServer(wssServerUrl);
 12339            ws.AddWebSocketService<DCLWebSocketService>("/" + wssServiceId);
 12340            ws.Start();
 12341        }
 042        catch (InvalidOperationException e)
 43        {
 044            ws.Stop();
 045            SocketException se = (SocketException)e.InnerException;
 046            if (se is { SocketErrorCode: SocketError.AddressAlreadyInUse })
 47            {
 048                return StartServer(port + 1, maxPort);
 49            }
 050            throw new InvalidOperationException(e.Message, e.InnerException);
 51        }
 52
 12353        return wssUrl;
 054    }
 55
 12356    public WebSocketCommunication()
 57    {
 12358        InitMessageTypeToBridgeName();
 59
 12360        DCL.DataStore.i.debugConfig.isWssDebugMode = true;
 61
 12362        string url = StartServer(5000, 5100);
 63
 12364        Debug.Log("WebSocket Server URL: " + url);
 65
 12366        DataStore.i.wsCommunication.url = url;
 67
 12368        DataStore.i.wsCommunication.communicationReady.Set(true);
 69
 12370        updateCoroutine = CoroutineStarter.Start(ProcessMessages());
 12371    }
 72
 73    private void InitMessageTypeToBridgeName()
 74    {
 75        // Please, use `Bridges` as a bridge name, avoid adding messages here. The system will use `Bridges` as the defa
 12376        messageTypeToBridgeName["SetDebug"] = "Main";
 12377        messageTypeToBridgeName["SetSceneDebugPanel"] = "Main";
 12378        messageTypeToBridgeName["ShowFPSPanel"] = "Main";
 12379        messageTypeToBridgeName["HideFPSPanel"] = "Main";
 12380        messageTypeToBridgeName["SetEngineDebugPanel"] = "Main";
 12381        messageTypeToBridgeName["SendSceneMessage"] = "Main";
 12382        messageTypeToBridgeName["LoadParcelScenes"] = "Main";
 12383        messageTypeToBridgeName["UnloadScene"] = "Main";
 12384        messageTypeToBridgeName["Reset"] = "Main";
 12385        messageTypeToBridgeName["CreateGlobalScene"] = "Main";
 12386        messageTypeToBridgeName["BuilderReady"] = "Main";
 12387        messageTypeToBridgeName["UpdateParcelScenes"] = "Main";
 12388        messageTypeToBridgeName["LoadProfile"] = "Main";
 12389        messageTypeToBridgeName["AddUserProfileToCatalog"] = "Main";
 12390        messageTypeToBridgeName["AddUserProfilesToCatalog"] = "Main";
 12391        messageTypeToBridgeName["RemoveUserProfilesFromCatalog"] = "Main";
 12392        messageTypeToBridgeName["ActivateRendering"] = "Main";
 12393        messageTypeToBridgeName["DeactivateRendering"] = "Main";
 12394        messageTypeToBridgeName["ForceActivateRendering"] = "Main";
 12395        messageTypeToBridgeName["AddWearablesToCatalog"] = "Main";
 12396        messageTypeToBridgeName["WearablesRequestFailed"] = "Main";
 12397        messageTypeToBridgeName["RemoveWearablesFromCatalog"] = "Main";
 12398        messageTypeToBridgeName["ClearWearableCatalog"] = "Main";
 12399        messageTypeToBridgeName["InitializeFriends"] = "Main";
 123100        messageTypeToBridgeName["UpdateFriendshipStatus"] = "Main";
 123101        messageTypeToBridgeName["UpdateUserPresence"] = "Main";
 123102        messageTypeToBridgeName["FriendNotFound"] = "Main";
 123103        messageTypeToBridgeName["AddMessageToChatWindow"] = "Main";
 123104        messageTypeToBridgeName["UpdateMinimapSceneInformation"] = "Main";
 123105        messageTypeToBridgeName["UpdateHotScenesList"] = "Main";
 123106        messageTypeToBridgeName["SetRenderProfile"] = "Main";
 123107        messageTypeToBridgeName["CrashPayloadRequest"] = "Main";
 123108        messageTypeToBridgeName["SetDisableAssetBundles"] = "Main";
 123109        messageTypeToBridgeName["DumpRendererLockersInfo"] = "Main";
 123110        messageTypeToBridgeName["PublishSceneResult"] = "Main";
 123111        messageTypeToBridgeName["BuilderProjectInfo"] = "Main";
 123112        messageTypeToBridgeName["BuilderInWorldCatalogHeaders"] = "Main";
 123113        messageTypeToBridgeName["AddAssets"] = "Main";
 123114        messageTypeToBridgeName["RunPerformanceMeterTool"] = "Main";
 123115        messageTypeToBridgeName["InstantiateBotsAtWorldPos"] = "Main";
 123116        messageTypeToBridgeName["InstantiateBotsAtCoords"] = "Main";
 123117        messageTypeToBridgeName["StartBotsRandomizedMovement"] = "Main";
 123118        messageTypeToBridgeName["StopBotsMovement"] = "Main";
 123119        messageTypeToBridgeName["RemoveBot"] = "Main";
 123120        messageTypeToBridgeName["ClearBots"] = "Main";
 121
 123122        messageTypeToBridgeName["Teleport"] = "CharacterController";
 123
 123124        messageTypeToBridgeName["SetRotation"] = "CameraController";
 125
 123126        messageTypeToBridgeName["ShowNotificationFromJson"] = "HUDController";
 123127        messageTypeToBridgeName["ConfigureHUDElement"] = "HUDController";
 123128        messageTypeToBridgeName["ShowTermsOfServices"] = "HUDController";
 123129        messageTypeToBridgeName["RequestTeleport"] = "HUDController";
 123130        messageTypeToBridgeName["ShowAvatarEditorInSignUp"] = "HUDController";
 123131        messageTypeToBridgeName["SetUserTalking"] = "HUDController";
 123132        messageTypeToBridgeName["SetUsersMuted"] = "HUDController";
 123133        messageTypeToBridgeName["ShowWelcomeNotification"] = "HUDController";
 123134        messageTypeToBridgeName["UpdateBalanceOfMANA"] = "HUDController";
 123135        messageTypeToBridgeName["SetPlayerTalking"] = "HUDController";
 123136        messageTypeToBridgeName["SetVoiceChatEnabledByScene"] = "HUDController";
 137
 123138        messageTypeToBridgeName["GetMousePosition"] = "BuilderController";
 123139        messageTypeToBridgeName["SelectGizmo"] = "BuilderController";
 123140        messageTypeToBridgeName["ResetObject"] = "BuilderController";
 123141        messageTypeToBridgeName["ZoomDelta"] = "BuilderController";
 123142        messageTypeToBridgeName["SetPlayMode"] = "BuilderController";
 123143        messageTypeToBridgeName["TakeScreenshot"] = "BuilderController";
 123144        messageTypeToBridgeName["ResetBuilderScene"] = "BuilderController";
 123145        messageTypeToBridgeName["SetBuilderCameraPosition"] = "BuilderController";
 123146        messageTypeToBridgeName["SetBuilderCameraRotation"] = "BuilderController";
 123147        messageTypeToBridgeName["ResetBuilderCameraZoom"] = "BuilderController";
 123148        messageTypeToBridgeName["SetGridResolution"] = "BuilderController";
 123149        messageTypeToBridgeName["OnBuilderKeyDown"] = "BuilderController";
 123150        messageTypeToBridgeName["UnloadBuilderScene"] = "BuilderController";
 123151        messageTypeToBridgeName["SetSelectedEntities"] = "BuilderController";
 123152        messageTypeToBridgeName["GetCameraTargetBuilder"] = "BuilderController";
 123153        messageTypeToBridgeName["PreloadFile"] = "BuilderController";
 123154        messageTypeToBridgeName["SetBuilderConfiguration"] = "BuilderController";
 123155        messageTypeToBridgeName["TriggerSelfUserExpression"] = "BuilderController";
 123156        messageTypeToBridgeName["AirdroppingRequest"] = "BuilderController";
 157
 123158        messageTypeToBridgeName["SetTutorialEnabled"] = "TutorialController";
 123159        messageTypeToBridgeName["SetTutorialEnabledForUsersThatAlreadyDidTheTutorial"] = "TutorialController";
 123160    }
 161
 162    IEnumerator ProcessMessages()
 163    {
 123164        var hudControllerGO = GameObject.Find("HUDController");
 123165        var mainGO = GameObject.Find("Main");
 166
 18766167        while (!requestStop)
 168        {
 18766169            lock (queuedMessages)
 170            {
 18766171                if (queuedMessagesDirty)
 172                {
 0173                    while (queuedMessages.Count > 0)
 174                    {
 0175                        DCLWebSocketService.Message msg = queuedMessages.Dequeue();
 176
 0177                        switch (msg.type)
 178                        {
 179                            // Add to this list the messages that are used a lot and you want better performance
 180                            case "SendSceneMessage":
 0181                                DCL.Environment.i.world.sceneController.SendSceneMessage(msg.payload);
 0182                                break;
 183                            case "Reset":
 0184                                DCL.Environment.i.world.sceneController.UnloadAllScenesQueued();
 0185                                break;
 186                            case "SetVoiceChatEnabledByScene":
 0187                                if (int.TryParse(msg.payload, out int value)) // The payload should be `string`, this wi
 188                                {
 0189                                    hudControllerGO.SendMessage(msg.type, value);
 190                                }
 0191                                break;
 192                            case "RunPerformanceMeterTool":
 0193                                if (float.TryParse(msg.payload, out float durationInSeconds)) // The payload should be `
 194                                {
 0195                                    mainGO.SendMessage(msg.type, durationInSeconds);
 196                                }
 0197                                break;
 198                            default:
 0199                                if (!messageTypeToBridgeName.TryGetValue(msg.type, out string bridgeName))
 200                                {
 0201                                    bridgeName = "Bridges"; // Default bridge
 202                                }
 203
 0204                                if (bridgeGameObjects.TryGetValue(bridgeName, out GameObject bridgeObject) == false)
 205                                {
 0206                                    bridgeObject = GameObject.Find(bridgeName);
 0207                                    bridgeGameObjects.Add(bridgeName, bridgeObject);
 208                                }
 209
 0210                                if (bridgeObject != null)
 211                                {
 0212                                    bridgeObject.SendMessage(msg.type, msg.payload);
 213                                }
 214                                break;
 215                        }
 216
 0217                        if (DCLWebSocketService.VERBOSE)
 218                        {
 0219                            Debug.Log(
 220                                "<b><color=#0000FF>WebSocketCommunication</color></b> >>> Got it! passing message of typ
 221                                msg.type);
 222                        }
 223                    }
 224                }
 18766225            }
 18766226            yield return null;
 227        }
 0228    }
 244229    public void Dispose() { ws.Stop(); }
 230}