private bool?serverResult_forfeited = null;                            //TODO: Check for this to not be null, then react.


        protected override void Awake()
        {
            base.Awake();

            Scene_Game.SetActive(false);
            Scene_ClientUI.SetActive(false);
        }
        /// <summary>
        /// Starts talking to the server on another thread.
        /// Returns that thread.
        /// </summary>
        private Thread ContactServer()
        {
            //If nothing is going on, try connecting to a server to ask for a match.
            if (!File.Exists(matchmakingDataFilePath))
            {
                Scene_ClientUI.SetActive(true);
                clientUI.SetIsFindingMatch(false);
                return(TalkToServer(new IPEndPoint(IPAddress.Parse(clientUI.ServerIP),
                                                   clientUI.ServerPort),
                                    TalkToServer_FirstContact));
            }
            else
            {
                //We must have a presence on the server already.
                var matchmakingData = GetMatchmakingData();

                //If we're still waiting for a match, check up on that.
                if (matchmakingData.OpponentName == null)
                {
                    Scene_ClientUI.SetActive(true);
                    clientUI.SetIsFindingMatch(true);
                    return(TalkToServer(matchmakingData.Server, TalkToServer_CheckMatch));
                }
                //Otherwise, pull the game state and load the board.
                else
                {
                    Scene_Game.SetActive(true);
                    return(TalkToServer(matchmakingData.Server, TalkToServer_GetMatchState));
                }
            }
        }
        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);
            }
        }