示例#1
0
    private IEnumerator ProcessLogin()
    {
        try
        {
            var loginDialog = UiManager.Instance.ShowModalRoot <LoginDialog>(this);
            yield return(StartCoroutine(loginDialog.WaitForHide()));

            G.Communicator.Channels.Last().StateChanged += (_, state) => { if (state == ChannelStateType.Closed)
                                                                           {
                                                                               ChannelEventDispatcher.Post(OnChannelClose, _);
                                                                           }
            };

            if (loginDialog.ReturnValue != null)
            {
                var result = (string)loginDialog.ReturnValue;
                ControlPanel.SetUserName(result);

                yield return(StartCoroutine(ProcessEnterRoom(G.User, "#general")));
            }
        }
        finally
        {
            _isBusy = false;
        }
    }
示例#2
0
    private static IEnumerator LoginCoroutine(IPEndPoint endPoint, string id, string password,
                                              ISlimTaskCompletionSource <bool> tcs, Action <string> progressReport)
    {
        // Connect

        if (progressReport != null)
        {
            progressReport("Connect");
        }

        var communicator = UnityCommunicatorFactory.Create();
        {
            var channelFactory = communicator.ChannelFactory;
            channelFactory.Type                = ChannelType.Udp;
            channelFactory.ConnectEndPoint     = endPoint;
            channelFactory.CreateChannelLogger = () => LogManager.GetLogger("Channel");
            channelFactory.PacketSerializer    = PacketSerializer.CreatePacketSerializer <DomainProtobufSerializer>();
        }

        var channel = communicator.CreateChannel();
        var t0      = channel.ConnectAsync();

        yield return(t0.WaitHandle);

        if (t0.Exception != null)
        {
            tcs.TrySetException(new Exception("Connect error\n" + t0.Exception, t0.Exception));
            yield break;
        }

        G.Communicator = communicator;

        // Login

        if (progressReport != null)
        {
            progressReport("Login");
        }

        channel = G.Communicator.Channels[0];
        var userLogin = channel.CreateRef <UserLoginRef>();
        var t1        = userLogin.Login(id, password);

        yield return(t1.WaitHandle);

        if (t1.Status != TaskStatus.RanToCompletion)
        {
            tcs.TrySetException(new Exception("Login Error\n" + t1.Exception, t1.Exception));
            yield break;
        }

        // Query User

        if (progressReport != null)
        {
            progressReport("Query User");
        }

        var userId        = t1.Result.Item1;
        var userInitiator = (UserInitiatorRef)t1.Result.Item2;

        if (userInitiator.IsChannelConnected() == false)
        {
            channel.Close();
            var t2 = userInitiator.ConnectChannelAsync();
            yield return(t2.WaitHandle);

            if (t2.Exception != null)
            {
                tcs.TrySetException(new Exception("ConnectToUser error\n" + t2.Exception, t2.Exception));
                yield break;
            }
        }

        var observer = communicator.ObserverRegistry.Create <IUserEventObserver>(UserEventProcessor.Instance, startPending: true);

        var t3 = userInitiator.Load(observer);

        yield return(t3.WaitHandle);

        if (t3.Exception != null)
        {
            if (t3.Exception is ResultException && ((ResultException)t3.Exception).ResultCode == ResultCodeType.UserNeedToBeCreated)
            {
                var inputDialog = UiInputBox.Show("Input your name:");
                yield return(inputDialog.WaitForHide());

                var userName = (string)inputDialog.ReturnValue;
                var t4       = userInitiator.Create(observer, userName);
                yield return(t4.WaitHandle);

                if (t4.Exception != null)
                {
                    tcs.TrySetException(new Exception("CreateUser error\n" + t4.Exception, t4.Exception));
                    communicator.ObserverRegistry.Remove(observer);
                    yield break;
                }
                G.UserContext = t4.Result;
            }
            else
            {
                tcs.TrySetException(new Exception("LoadUser error\n" + t3.Exception, t3.Exception));
                communicator.ObserverRegistry.Remove(observer);
                yield break;
            }
        }
        else
        {
            G.UserContext = t3.Result;
        }

        G.User   = userInitiator.Cast <UserRef>();
        G.UserId = userId;

        communicator.Channels.Last().StateChanged += (_, state) =>
        {
            if (state == ChannelStateType.Closed)
            {
                ChannelEventDispatcher.Post(OnChannelClose, _);
            }
        };

        tcs.TrySetResult(true);

        observer.GetEventDispatcher().Pending = false;
    }
示例#3
0
    private IEnumerator ProcessEnterRoom(UserRef user, string roomName)
    {
        // Spawn new room item

        var go        = UiHelper.AddChild(ContentPanel, ChatPanelTemplate);
        var chatPanel = go.GetComponent <ChatPanel>();

        // Try to enter the room

        var observer = G.Communicator.ObserverRegistry.Create <IRoomObserver>(chatPanel);

        observer.GetEventDispatcher().Pending      = true;
        observer.GetEventDispatcher().KeepingOrder = true;
        var t1 = user.EnterRoom(roomName, observer);

        yield return(t1.WaitHandle);

        if (t1.Status != TaskStatus.RanToCompletion)
        {
            G.Communicator.ObserverRegistry.Remove(observer);
            DestroyObject(go);
            UiMessageBox.Show("Enter room error:\n" + t1.Exception);
            yield break;
        }

        // Spawn new room item

        var occupant = (OccupantRef)t1.Result.Item1;

        if (occupant.IsChannelConnected() == false)
        {
            yield return(occupant.ConnectChannelAsync().WaitHandle);
        }
        chatPanel.SetOccupant(occupant);
        chatPanel.SetRoomInfo(t1.Result.Item2);
        chatPanel.ExitButtonClicked = () => OnRoomExitClick(roomName);

        var item = new RoomItem
        {
            ChatPanel = chatPanel,
            Occupant  = occupant,
            Observer  = (RoomObserver)observer,
            Channel   = (IChannel)occupant.RequestWaiter
        };

        _roomItemMap.Add(roomName, item);
        ControlPanel.AddRoomItem(roomName);
        observer.GetEventDispatcher().Pending = false;

        item.Channel.StateChanged += (_, state) =>
        {
            ChannelEventDispatcher.Post(o =>
            {
                if (state == ChannelStateType.Closed)
                {
                    if (_roomItemMap.ContainsKey(roomName))
                    {
                        OnRoomExitClick(roomName);
                    }
                }
            });
        };

        // Select

        OnRoomItemClick(roomName);
    }
示例#4
0
    private IEnumerator ProcessJoinGameInternal()
    {
        G.Logger.Info("ProcessJoinGame");

        // Finding Game
        // Register user to pairing queue and waiting for 5 secs.

        LoadingText.text = "Finding Game...";

        _pairedGame = null;

        var pairingObserver = G.Communicator.ObserverRegistry.Create <IUserPairingObserver>(this);

        yield return(G.User.RegisterPairing(pairingObserver).WaitHandle);

        var startTime = DateTime.Now;

        while ((DateTime.Now - startTime).TotalSeconds < 5 && _pairedGame == null && _isLeaveRequested == false)
        {
            yield return(null);
        }

        G.Communicator.ObserverRegistry.Remove(pairingObserver);

        if (_isLeaveRequested)
        {
            yield break;
        }

        if (_pairedGame == null)
        {
            yield return(G.User.UnregisterPairing().WaitHandle);

            if (_isLeaveRequested == false)
            {
                yield return(UiMessageBox.Show("Cannot find game").WaitForHide());
            }
            SceneManager.LoadScene("MainScene");
            yield break;
        }

        // Join Game

        var gameObserver = G.Communicator.ObserverRegistry.Create <IGameObserver>(this, startPending: true);

        gameObserver.GetEventDispatcher().KeepingOrder = true;

        var roomId  = _pairedGame.Item1;
        var joinRet = G.User.JoinGame(roomId, gameObserver);

        yield return(joinRet.WaitHandle);

        if (joinRet.Exception != null)
        {
            G.Communicator.ObserverRegistry.Remove(gameObserver);
            var box = UiMessageBox.Show("Failed to join\n" + joinRet.Exception);
            yield return(StartCoroutine(box.WaitForHide()));

            SceneManager.LoadScene("MainScene");
        }

        _gameObserver = gameObserver;
        _gameInfo     = joinRet.Result.Item3;
        _myPlayerId   = joinRet.Result.Item2;
        _myPlayer     = (GamePlayerRef)joinRet.Result.Item1;

        if (_myPlayer.IsChannelConnected() == false)
        {
            var connectTask = _myPlayer.ConnectChannelAsync();
            yield return(connectTask.WaitHandle);

            if (connectTask.Exception != null)
            {
                var box = UiMessageBox.Show("Failed to connect\n" + joinRet.Exception);
                G.Communicator.ObserverRegistry.Remove(gameObserver);
                yield return(StartCoroutine(box.WaitForHide()));

                _myPlayer = null;
                yield break;
            }
            ((IChannel)_myPlayer.RequestWaiter).StateChanged += (_, state) =>
            {
                if (state == ChannelStateType.Closed)
                {
                    ChannelEventDispatcher.Post(OnChannelClose, _);
                }
            };
        }

        gameObserver.GetEventDispatcher().Pending = false;
        LoadingText.text = "Waiting for " + _pairedGame.Item2 + "...";
    }