Beispiel #1
0
        /// <summary>
        /// Initializes the controller. Must be called immediately upon loading the home
        /// screen in order to correctly initialize the scene.
        /// </summary>
        ///
        /// <param name="state">
        /// The <see cref="ClientState"/> object for the current client.
        /// </param>
        public async UniTask <NextScreen> Run(ClientState state)
        {
            _accountIdDisplay.text = state.AccountId().ToString();
            _pointsDisplay.text    = state.Points().ToString();

            // Wait for the player to hit the "Play" button since it's the only
            // interactive element in the scene.
            await _playButton.OnClickAsync();

            return(NextScreen.Match);
        }
Beispiel #2
0
        private async void Start()
        {
            try
            {
                // Create the underlying state data for the client.
                _state = new ClientState();

                // TODO: Handle an exception being thrown as a result of the connection failing.
                // TODO: Make server address configurable.
                _socket = await WebSocket.ConnectAsync(new Uri("ws://localhost:3030/client"));

                // HACK: Due to a bug in WebSocketSharp, the first message that we'll receive
                // when waiting will be the initial ping sent by the server to trigger the
                // client connection.
                var pingHack = await _socket.RecvStringAsync();

                Debug.Assert(pingHack == "ping", $"Received unexpected first message: {pingHack}");

                Debug.Log("Established connection with server, beginning handshake");

                // TODO: Load any cached credentials and add them to the client state.

                // Perform handshake and initialization sequence with the server:
                //
                // * The client sends account ID and initial configuration data.
                // * Server sends current account data and any updated cache data.
                _socket.SendString(_state.CreateHandshakeRequest());
                if (!_state.HandleHandshakeResponse(await _socket.RecvStringAsync()))
                {
                    // TODO: Add better handling for the case where we failed to connect to
                    // the server. Obviously we need better error handling coming from the
                    // Rust side, be we should probably have some option for the player to
                    // re-attempt the connection.
                    Debug.LogError("Handshake with server failed :'(");
                    return;
                }

                Debug.Log($"Handshake completed, account ID: {_state.AccountId()}, points balance: {_state.Points()}");

                // Load the home screen once everything has been loaded.
                await SceneManager.LoadSceneAsync("Home");

                // Once the home screen has loaded, initialize the home screen controller.
                var nextScreen = await FindObjectOfType <HomeController>().Run(_state);

                while (true)
                {
                    switch (nextScreen)
                    {
                    case NextScreen.Home:
                    {
                        // Unload the current scene and load the home scene.
                        await SceneManager.LoadSceneAsync("Home");

                        // Transfer control to the home controller and wait for it to finish.
                        nextScreen = await FindObjectOfType <HomeController>().Run(_state);
                    }
                    break;

                    case NextScreen.Match:
                    {
                        // Unload the current scene and load the gameplay scene.
                        await SceneManager.LoadSceneAsync("Gameplay");

                        // Transfer control to the match controller and wait for it finish.
                        nextScreen = await FindObjectOfType <MatchController>().Run(_state, _socket);
                    }
                    break;

                    default:
                    {
                        throw new NotImplementedException(
                                  $"Unhandled value for next screen: {nextScreen}");
                    }
                    }
                }
            }
            catch (TaskCanceledException exception)
            {
                Debug.Log($"Main task was canceled: {exception}");
            }
            catch (OperationCanceledException exception)
            {
                Debug.Log($"Operation canceled during main task: {exception}");
            }
        }