Exemplo n.º 1
0
        /// <summary>
        /// Tries to read a message of the given type from the given stream.
        /// If there is an error, outputs the error to the UI and returns null.
        /// Otherwise, returns the message.
        /// </summary>
        /// <param name="thisAction">Used when printing an error.</param>
        private T TryReadMsg <T>(BinaryReader reader, string thisAction)
            where T : GameMessageBase
        {
            GameMessageBase message = null;

            if (!Try(() => message = GameMessageBase.Read(reader)))
            {
                clientUI.SetErrorMsg("Unable to get message " + thisAction);
                return(null);
            }

            if (message.Type == Networking.Messages.Types.Error &&
                typeof(T) != typeof(Networking.Messages.Error))
            {
                var errMsg = (Networking.Messages.Error)message;
                clientUI.SetErrorMsg("Error " + thisAction + ": " + errMsg.Msg);
                return(null);
            }

            if (message.GetType() != typeof(T))
            {
                clientUI.SetErrorMsg("Unexpected message type " + message.GetType().Name +
                                     " " + thisAction);
                return(null);
            }

            return((T)message);
        }
Exemplo n.º 2
0
        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;
                }
            }
        }
Exemplo n.º 3
0
        //The below methods contain the actual client-server message-passing code.
        //They are written to line up with the messaging code in Server.cs.

        private void TalkToServer_FirstContact(TcpClient client, NetworkStream serverStream,
                                               BinaryWriter serverWriter, BinaryReader serverReader)
        {
            //Ask the server to find a game for me.
            var msg_findGame = new Networking.Messages.FindGame(clientUI.MyName,
                                                                GameID);

            if (!Try(() => GameMessageBase.Write(msg_findGame, serverWriter)))
            {
                clientUI.SetErrorMsg("Couldn't send 'FindGame' to server");
                return;
            }

            //Check the response.
            var queueResult = TryReadMsg <Networking.Messages.SuccessfullyInQueue>(
                serverReader,
                "getting 'FindGame' response");

            if (queueResult == null)
            {
                return;
            }

            //Store the result.
            var outData = new ClientMatchmakingData((IPEndPoint)client.Client.RemoteEndPoint,
                                                    queueResult.PlayerID);

            SetMatchmakingData(outData);
        }
Exemplo n.º 4
0
        private void TalkToServer_Forfeit(TcpClient client, NetworkStream serverStream,
                                          BinaryWriter serverWriter, BinaryReader serverReader)
        {
            var matchData = GetMatchmakingData();

            //Send the request.
            var request = new Networking.Messages.ForfeitGame(matchData.PlayerID);

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

            //Receive an acknowledgement.
            var ack = TryReadMsg <Networking.Messages.Acknowledge>(serverReader,
                                                                   "getting 'Forfeit' ack");

            serverResult_forfeited = (ack != null);
        }
Exemplo n.º 5
0
        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);
            }
        }