private void TalkToServer_GetMatchState(TcpClient client, NetworkStream serverStream,
                                                BinaryWriter serverWriter, BinaryReader serverReader)
        {
            //Send the request.
            var matchData = GetMatchmakingData();
            var request   = new Networking.Messages.GetGameState(matchData.PlayerID,
                                                                 matchData.LastKnownMove);

            if (!Try(() => GameMessageBase.Write(request, serverWriter)))
            {
                clientUI.SetErrorMsg("Error sending 'GetGameState' request");
                return;
            }

            //Get the state from the server and load it.
            var gameState = TryReadMsg <Networking.Messages.GameState>(serverReader,
                                                                       "getting game state");

            if (gameState == null)
            {
                return;
            }
            serverResult_stateToLoad = gameState;

            //If the game has ended, we need to tell the server that we definitely received it.
            if (Networking.Messages.Extensions.IsGameOver(gameState.MatchState))
            {
                var acknowledge = new Networking.Messages.Acknowledge();
                if (!Try(() => GameMessageBase.Write(acknowledge, serverWriter)))
                {
                    clientUI.SetErrorMsg("Error sending 'Ack' after game state");
                    return;
                }
            }
        }
        private void LoadGameState(Networking.Messages.GameState state)
        {
            //Load the board.
            using (var boardStream = new MemoryStream(state.BoardState))
                using (var boardReader = new BinaryReader(boardStream))
                    TheBoard.Deserialize(boardReader);

            //TODO: Load up the rest of the match state.
        }
        private void TalkToServer_CheckMatch(TcpClient client, NetworkStream serverStream,
                                             BinaryWriter serverWriter, BinaryReader serverReader)
        {
            var matchMakingData = GetMatchmakingData();

            //Ask the server whether a match was found.
            var initialMsg = new Networking.Messages.CheckOpponentFound(matchMakingData.PlayerID);

            if (!Try(() => GameMessageBase.Write(initialMsg, serverWriter)))
            {
                clientUI.SetErrorMsg("Couldn't send 'CheckMatch' message");
                return;
            }

            //Get the response.
            var opponentInfo = TryReadMsg <Networking.Messages.FoundOpponent>(
                serverReader,
                "getting 'CheckMatch' response");

            if (opponentInfo == null)
            {
                return;
            }

            //If an opponent hasn't been found yet, check in again later.
            if (opponentInfo.OpponentName == null)
            {
                return;
            }

            //If this player is going first, we need to generate the initial game board.
            //Note that a game board has already been generated; we can just use that.
            if (opponentInfo.AmIGoingFirst)
            {
                byte[] boardBytes = null;
                using (var boardStream = new MemoryStream())
                {
                    using (var boardWriter = new BinaryWriter(boardStream))
                        TheBoard.Serialize(boardWriter);
                    boardBytes = boardStream.GetBuffer();
                }

                var boardStateMsg = new Networking.Messages.NewBoard(boardBytes,
                                                                     MatchStates.Player1Turn);
                if (!Try(() => GameMessageBase.Write(boardStateMsg, serverWriter)))
                {
                    clientUI.SetErrorMsg("Couldn't send 'NewBoard' response");
                    return;
                }
            }
            //Otherwise, we need to get the current game state.
            else
            {
                //Get and load the state.
                var gameState = TryReadMsg <Networking.Messages.GameState>(
                    serverReader,
                    "getting first 'GameState'");
                if (gameState == null)
                {
                    return;
                }
                serverResult_stateToLoad = gameState;

                //Acknowledge.
                var acknowledge = new Networking.Messages.Acknowledge();
                if (!Try(() => GameMessageBase.Write(acknowledge, serverWriter)))
                {
                    clientUI.SetErrorMsg("Couldn't send 'Ack' after first game state");
                    return;
                }

                //Start the game UI.
                Scene_ClientUI.SetActive(false);
                Scene_Game.SetActive(true);
            }
        }