示例#1
0
        private void SocketHandler_GetGameState(Messages.GetGameState msg, NetworkStream stream,
                                                BinaryReader streamReader, BinaryWriter streamWriter)
        {
            var game = FindGame(msg.PlayerID);

            if (game == null)
            {
                var errMsg = new Messages.Error("Couldn't find game with ID " + msg.PlayerID);
                Try(() => Messages.Base.Write(errMsg, streamWriter),
                    "sending 'unknown game ID' error");
                return;
            }

            byte[][] recentMoves = new byte[game.AllMoves.Count - msg.LastKnownMovement][];
            for (int i = 0; i < recentMoves.Length; ++i)
            {
                recentMoves[i] = game.AllMoves[i + msg.LastKnownMovement];
            }

            var gameMsg = new Messages.GameState(game.BoardState, recentMoves,
                                                 game.MatchState, game.Player1ID, game.Player2ID);

            if (!Try(() => Messages.Base.Write(gameMsg, streamWriter),
                     "telling game state"))
            {
                return;
            }

            //If the game is over, make sure the player acknowledges that fact.
            if (gameMsg.MatchState.IsGameOver())
            {
                Messages.Base _acknowledgeMsg = null;
                if (!Try(() => _acknowledgeMsg = Messages.Base.Read(streamReader),
                         "Getting acknowledgement from client in 'CheckOpponentFound'"))
                {
                    return;
                }
                if (!(_acknowledgeMsg is Messages.Acknowledge))
                {
                    Try(() => { throw new Exception("Expected Acknowledgement, got " + _acknowledgeMsg.Type); },
                        "casting message to acknowledgement");
                }

                //Remove the game from various data structures.
                lock (lock_finishedGames)
                    finishedGamesByUnacknowledgedPlayer.Remove(msg.PlayerID);
                lock (lock_activeGames)
                    activeGames.Remove(game);
            }
        }
示例#2
0
        private void SocketHandler_CheckOpponentFound(Messages.CheckOpponentFound msg,
                                                      NetworkStream stream,
                                                      BinaryReader streamReader,
                                                      BinaryWriter streamWriter)
        {
            //Get the player with the given ID.
            var playerData = playerMatcher.TryGetKey(msg.PlayerID);

            if (!playerData.HasValue)
            {
                var failMsg = new Messages.Error("Player ID " + msg.PlayerID +
                                                 " not found in matchmaking queue");
                Try(() => Messages.Base.Write(failMsg, streamWriter),
                    "Sending error msg");

                return;
            }

            //See if he has a match yet.
            bool wasFirst;
            var  tryMatch = playerMatcher.TryPop(playerData.Value, out wasFirst);

            if (tryMatch.HasValue)
            {
                var match = tryMatch.Value;

                //If error occurs, we should leave the player in the queue.
                System.Action <Exception> onFailure = e => playerMatcher.Push(playerData.Value, match);

                //Tell the player he has an opponent.
                var foundPlayerMsg = new Messages.FoundOpponent(match.Name, match.PlayerID, wasFirst);
                if (!Try(() => Messages.Base.Write(foundPlayerMsg, streamWriter),
                         "Sending opponent msg", onFailure))
                {
                    return;
                }

                //If the player who asked is going first, get the board state from him.
                if (wasFirst)
                {
                    //Get the initial board state from the player.
                    Messages.Base _newBoardMsg = null;
                    if (!Try(() => _newBoardMsg = Messages.Base.Read(streamReader),
                             "Getting board state", onFailure))
                    {
                        return;
                    }

                    var newBoardMsg = _newBoardMsg as Messages.NewBoard;
                    if (newBoardMsg == null)
                    {
                        onFailure(null);

                        string errMsg = "Unexpected message type " + _newBoardMsg.Type + "; expected NewBoard";
                        Try(() => Messages.Base.Write(new Messages.Error(errMsg), streamWriter),
                            "Sending error msg from 'init board state'");

                        return;
                    }

                    //Record the initial game state.
                    GameState state = new GameState();
                    state.AllMoves   = new List <byte[]>();
                    state.BoardState = newBoardMsg.BoardState;
                    state.MatchState = newBoardMsg.MatchState;
                    state.Player1ID  = playerData.Value.PlayerID;
                    state.Player2ID  = match.PlayerID;
                    lock (lock_activeGames)
                    {
                        activeGames.Add(state);
                    }
                }
                //Otherwise, send the game state to him.
                else
                {
                    var gameState = FindGame(playerData.Value.PlayerID);
                    if (gameState == null)
                    {
                        Try(() => { throw new NullReferenceException("Couldn't find game with ID " + playerData.Value.PlayerID); },
                            "sending game state to player",
                            onFailure, streamWriter);
                        return;
                    }

                    //Send the game state.
                    var gameStateMsg = new Messages.GameState(gameState.BoardState,
                                                              gameState.AllMoves.ToArray(),
                                                              gameState.MatchState,
                                                              gameState.Player1ID, gameState.Player2ID);
                    if (!Try(() => Messages.Base.Write(gameStateMsg, streamWriter),
                             "Giving game state to player", onFailure))
                    {
                        return;
                    }

                    //Wait for an acknowledgement.
                    Messages.Base _acknowledgeMsg = null;
                    if (!Try(() => _acknowledgeMsg = Messages.Base.Read(streamReader),
                             "Getting acknowledgement from client in 'CheckOpponentFound'",
                             onFailure))
                    {
                        return;
                    }
                    if (!(_acknowledgeMsg is Messages.Acknowledge))
                    {
                        onFailure(null);
                    }
                }
            }
            else
            {
                var nullMsg = new Messages.FoundOpponent(null, ulong.MaxValue, false);
                Try(() => Messages.Base.Write(nullMsg, streamWriter),
                    "Sending \"null opponent\" msg");
            }
        }