Beispiel #1
0
 //666 Roger added another argument
 private void UpdateTexture(GameObject videoObject, bool flipped, ref Texture2D videoTexture, IFrame frame, FramePixelFormat format)
 {
     if (frame != null)
     {
         if (videoTexture == null)
         {
             DebugLog.AddEntry("Video texture: " + frame.Width + "x" + frame.Height + " Format:" + format);
         }
         UnityMediaHelper.UpdateTexture(frame, ref videoTexture);
         videoObject.GetComponent <UITexture>().mainTexture = videoTexture;
         if (flipped)
         {
             videoObject.transform.rotation = Quaternion.Euler(0, 180f, 180f);
         }
         else
         {
             videoObject.transform.rotation = Quaternion.Euler(0, 0, 180f);
         }
     }
     else
     {
         // app shutdown. reset values
         videoObject.GetComponent <UITexture>().mainTexture = null;
         videoObject.transform.rotation = Quaternion.Euler(0, 0, 0);
     }
 }
Beispiel #2
0
 static private void HandleException(string condition, string stackTrace, LogType type)
 {
     if (type == LogType.Exception)
     {
         DebugLog.AddEntry(condition);
         DebugLog.AddEntry(stackTrace);
         Globals.exceptionMessage = condition;
     }
 }
Beispiel #3
0
 private void SendInitialState()
 {
     // if there is an app currently open then
     // send it's restore state to the client
     if (currentApp != null)
     {
         DebugLog.AddEntry("send initial state for " + currentApp.GetName());
         var bytes = currentApp.GetRestoreState();
         SendMessage(bytes);
     }
 }
Beispiel #4
0
    protected override void HandleRestoreState(byte[] bytes)
    {
        var state = Packet.Deserialize <RestoreState>(bytes);

        DebugLog.AddEntry("restore app state");

        questionImage.mainTexture = questionImages[state.questionID].texture;

        currentQuestionID = state.questionID;

        foreach (var key in state.questions.Keys)
        {
            soundFields[key].text = state.questions[key];
        }
        UpdateGUIState();
    }
Beispiel #5
0
    private void ConnectedAndReady(object context)
    {
        DebugLog.AddEntry("connected and ready");
        PrepareRoleSpecific();

      #if UNITY_ANDROID
        debugLogButton.SetActive(true);
      #endif

        // TESTING - open app if we're running the editor as the therapist
      #if UNITY_EDITOR
        if (Globals.isTherapist)
        {
            OpenApp(Gameboard.Semantic2);
        }
      #endif
    }
Beispiel #6
0
    private void RoleChanged(Role role)
    {
        // create account info
        account = new Account();

        // windows builds connect on a specific address
        // as to not interer with testing on macs
      #if UNITY_STANDALONE_WIN
        account.address = "com.c-star.slptest.win";
      #else
        account.address = "com.c-star.slptest";
      #endif

        account.server   = "stun:stun.because-why-not.com:443";
        account.server2  = "stun:stun.l.google.com:19302";
        account.user     = "******" + PlayerPrefs.GetString(PREFS.PATIENT_ID);
        account.password = "******";
        account.url      = "ws://signaling.because-why-not.com/callapp";

        // TODO: testing
        // account.server = "stun:129.252.69.147:443";
        // account.url = "ws://129.252.69.147/callapp";

        DebugLog.AddEntry("Connecting as " + role + "...");
        DebugLog.AddEntry("    account.address: " + account.address);
        DebugLog.AddEntry("    account.user: "******"    account.password: " + account.password);

        Globals.role = role;
        Connect();
        sideBar.SetActive(true);

        // the therapist always controls the random seed
        if (role == Role.Therapist)
        {
            Globals.randomSeed = UnityEngine.Random.seed;
            LoadAppPanels();
        }

        // call after a delay to ensure startup process is complete
        // TODO: but we're not really connected!!
        DelayedAction.InvokeMethod(0.0f, ConnectedAndReady);
    }
Beispiel #7
0
    public void Show(GameObject parent, BaseAppParams paras)
    {
        DebugLog.AddEntry("show app " + GetName());

        caller     = paras.caller;
        stats      = new Stats();
        instanceID = Globals.GetNewAppInstanceID();

        panel.SetActive(true);
        panel.transform.localPosition = parent.transform.localPosition;

        if (!didLoad)
        {
            HandleLoad();
            didLoad = true;
        }

        HandleShow();
    }
Beispiel #8
0
    private void LoadAppPanels()
    {
        // don't double-load
        if (apps.Count > 0)
        {
            return;
        }

        DebugLog.AddEntry("loading app panels");

        // before loading app panels make sure the
        // the random seed is set to our value
        UnityEngine.Random.seed = Globals.randomSeed;
        DebugLog.AddEntry("random seed: " + Globals.randomSeed);

        foreach (var board in gameBoards)
        {
            LoadApp(board);
        }
    }
Beispiel #9
0
    private void ShowApp(BaseApp app)
    {
        if (currentApp != null)
        {
            Globals.FatalError("already showing an app");
        }

        currentApp = app;

        var paras = new BaseAppParams();

        paras.caller = caller;
        app.Show(gameboardPanel, paras);

        // send a handshake action so we know the client is ready
        if (Globals.isPatient)
        {
            DebugLog.AddEntry("handshake with therapist for appID " + currentApp.appID);
            SendMessage(new SystemMessage(currentApp.appID, AppActions.HandShake), false);
        }
    }
Beispiel #10
0
    private void Connect()
    {
        DebugLog.AddEntry("connecting...");

        // create network config
        if (networkConfig == null)
        {
            networkConfig = CreateNetworkConfig(account);
        }

        // setup caller
        caller = UnityCallFactory.Instance.Create(networkConfig);
        if (caller == null)
        {
            Debug.Log("Failed to create caller");
            return;
        }

        caller.LocalFrameEvents = true;
        caller.CallEvent       += HandleCallEvent;

        // setup media config
        if (mediaConfig == null)
        {
            mediaConfig = CreateMediaConfig();

            // prefer the external video device
            if (UnityCallFactory.Instance.CanSelectVideoDevice())
            {
                string[] videoDevices = UnityCallFactory.Instance.GetVideoDevices();

                // show all video device names
                for (int i = 0; i < videoDevices.Length; i++)
                {
                    var name = videoDevices[i];
                    DebugLog.AddEntry("video device #" + i + ": " + name);
                }

                var preferredDevice = PlayerPrefs.GetInt(PREFS.VIDEO_DEVICE);
                if (preferredDevice < videoDevices.Length)
                {
                    mediaConfig.VideoDeviceName = videoDevices[preferredDevice];
                }
                else
                {
                    // use defualt device if the preferred device is out of range
                    mediaConfig.VideoDeviceName = videoDevices[0];
                }
            }
            else
            {
                mediaConfig.VideoDeviceName = UnityCallFactory.Instance.GetDefaultVideoDevice();
            }
            DebugLog.AddEntry("Using video device: " + mediaConfig.VideoDeviceName);
        }

        caller.Configure(mediaConfig);

        // start listening...
        if (Globals.role == Role.Therapist)
        {
            DebugLog.AddEntry("server listening for connections on " + account.address + "...");
            SetStatusMessageText("Listening for connections on " + account.address + "...");
            caller.Listen(account.address);
        }
        else
        {
            DebugLog.AddEntry("client connecting to " + account.address + "...");
            SetStatusMessageText("Connecting to " + account.address + "...");
            caller.Call(account.address);
        }
    }
Beispiel #11
0
    private void HandleCallEvent(object sender, CallEventArgs e)
    {
        switch (e.Type)
        {
        case CallEventType.CallAccepted: {
            ConnectionId connID = ((CallAcceptedEventArgs)e).ConnectionId;
            DebugLog.AddEntry("CallAccepted: " + connID);
            Globals.therapistOnlyTesting = false;
            // send intial state when clients are accepted
            // note that this even is received when clients
            // are connected to the server so we need to filter
            // out CallAccepted events which are the server
            if (Globals.role == Role.Therapist)
            {
                SendMessage(new SystemMessage(0, AppActions.Login), false);
                SendInitialState();
            }
            SetStatusMessageText("");
            break;
        }

        case CallEventType.CallEnded: {
            ConnectionId connID = ((CallEndedEventArgs)e).ConnectionId;
            DebugLog.AddEntry("CallEnded: " + connID);
            if (currentApp != null)
            {
                currentApp.Disconnect();
                if (Globals.role == Role.Patient)
                {
                    CloseCurrentApp();
                }
            }
            remoteVideo.GetComponent <UITexture>().mainTexture = null;
            Disconnect();
            Connect();
            break;
        }

        case CallEventType.ListeningFailed: {
            ErrorEventArgs args = e as ErrorEventArgs;
            // TODO: when do we get this? if the network is down show an error
            DebugLog.AddEntry("ListeningFailed");
            // Globals.FatalError("Listening failed. Is another server running?");
            SetStatusMessageText("Listening failed (" + args.ErrorMessage + ")");
            break;
        }

        case CallEventType.ConnectionFailed: {
            ErrorEventArgs args = e as ErrorEventArgs;
            DebugLog.AddEntry("Connection failed error: " + args.ErrorMessage);
            SetStatusMessageText("Connection failed (" + args.ErrorMessage + ")");
            if (Globals.role == Role.Patient)
            {
                Invoke("Reconnect", CLIENT_RETRY_DELAY);
            }
            else
            {
                // does this ever happen to the server?
                Globals.FatalError("ConnectionFailed!");
            }
            break;
        }

        case CallEventType.ConfigurationFailed: {
            ErrorEventArgs args = e as ErrorEventArgs;
            DebugLog.AddEntry("Configuration failed error: " + args.ErrorMessage);
            Disconnect();
            break;
        }

        case CallEventType.FrameUpdate: {
            if (e is FrameUpdateEventArgs)
            {
                UpdateFrame((FrameUpdateEventArgs)e);
            }
            break;
        }

        case CallEventType.DataMessage: {
            var args = e as DataMessageEventArgs;
            HandleMessage(args.Content);
            break;
        }

        // case CallEventType.Message: {
        //   MessageEventArgs args = e as MessageEventArgs;
        //   HandleSystemMessage(args.Content);
        //   break;
        // }

        case CallEventType.WaitForIncomingCall: {
            WaitForIncomingCallEventArgs args = e as WaitForIncomingCallEventArgs;
            // the server is connected so present the gui
            SetGUIVisible(true);
            // if there is an app already open the pass the new caller
            if (currentApp != null)
            {
                currentApp.Reconnect(caller);
            }
            break;
        }
        }
    }
Beispiel #12
0
    private void HandleMessage(byte[] bytes)
    {
        var header = Packet.GetHeader(bytes);

        // DebugLog.AddEntry("header.protocol: "+header.protocol+" sender:"+header.sender);

        switch (header.protocol)
        {
        case MessageHeader.HEADER_PROTOCOL_SYSTEM: {
            var msg = Packet.Deserialize <SystemMessage>(bytes);

            switch (msg.action)
            {
            case AppActions.Open:
                CloseCurrentApp();
                // sync the global random seed with the therapist
                // who sends the open message
                Globals.SetRandomSeed(msg.randomSeed);
                ShowApp(msg.appID);
                break;

            case AppActions.Close:
                CloseCurrentApp();
                break;

            case AppActions.HandShake:
                if (currentApp == null)
                {
                    Globals.FatalError("got handshake without active app");
                }
                if (currentApp.appID != msg.appID)
                {
                    Globals.FatalError("handshake appID doesn't match current app (got " + header.appID + " expected " + currentApp.appID + ")");
                }
                currentApp.ClientIsReady();
                break;

            case AppActions.Login:
                DebugLog.AddEntry("login patient");
                Globals.randomSeed = msg.randomSeed;
                LoadAppPanels();
                break;

            case AppActions.FlipTherapistVideo:
                if (Globals.isTherapist)
                {
                    localVideoFlipped = !localVideoFlipped;
                }
                else
                {
                    remoteVideoFlipped = !remoteVideoFlipped;
                }
                break;

            case AppActions.FlipPatientVideo:
                if (Globals.isPatient)
                {
                    localVideoFlipped = !localVideoFlipped;
                }
                else
                {
                    remoteVideoFlipped = !remoteVideoFlipped;
                }
                break;
            }
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_RESTORE: {
            // restore app state if the message was sent from
            // the therapist and we are the patient
            if (header.sender == Role.Therapist && Globals.role == Role.Patient)
            {
                DebugLog.AddEntry("restore app ID " + header.appID);

                // show the app first
                if (!IsAppActive(header.appID))
                {
                    ShowApp(header.appID);
                }

                if (currentApp == null)
                {
                    Globals.FatalError("attempting restore without active app");
                }
                currentApp.RestoreState(bytes);
            }
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_APP: {
            // NOTE: what was this for???
            // && header.sender != Globals.role
            if (currentApp != null)
            {
                currentApp.ReceiveMessage(bytes);
            }
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_APP_PARAMS: {
            if (currentApp != null)
            {
                currentApp.ReceiveParams(bytes);
            }
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_SKETCH: {
            sketchPad.HandleMessage(bytes);
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_MOUSE_INDICATOR: {
            var msg = Packet.Deserialize <CursorMessage>(bytes);
            // play clicking sound
            if (header.sender == Role.Patient)
            {
                AudioSource.PlayClipAtPoint(mouseClickSound, transform.position);
            }
            StartCoroutine(AnimateMouseIndicator(new Vector3(msg.x, msg.y)));
            break;
        }

        case MessageHeader.HEADER_PROTOCOL_CURSOR: {
            var msg = Packet.Deserialize <CursorMessage>(bytes);

            if (msg.x == -1 && msg.y == -1)
            {
                therapistCursor.SetActive(false);
            }
            else
            {
                // convert back to screen coords to apply offset in pixels
                var pos = camera.WorldToScreenPoint(new Vector3(msg.x, msg.y, 1));
                // var offset = new Vector3(-6 * therapistCursor.transform.localScale.x, 28 * therapistCursor.transform.localScale.y, 0);
                var offset = new Vector3(-24 * therapistCursor.transform.localScale.x, 87 * therapistCursor.transform.localScale.y, 0);
                pos -= offset;

                therapistCursor.SetActive(true);
                therapistCursor.transform.position = camera.ScreenToWorldPoint(pos);
            }
            break;
        }

        default: {
            Globals.FatalError("invalid message protocol: " + header.protocol);
            break;
        }
        }
    }