Ejemplo n.º 1
0
        public static Base Read(BinaryReader reader)
        {
            Base b = null;

            var type = (Types)reader.ReadByte();

            switch (type)
            {
            case Types.Error: b = new Error(null); break;

            case Types.Acknowledge: b = new Acknowledge(); break;

            case Types.FindGame: b = new FindGame(null, 0); break;

            case Types.SuccessfullyInQueue: b = new SuccessfullyInQueue(0); break;

            case Types.CheckOpponentFound: b = new CheckOpponentFound(0); break;

            case Types.FoundOpponent: b = new FoundOpponent(null, 0, false); break;

            case Types.NewBoard: b = new NewBoard(null, MatchStates.Tie); break;

            case Types.GetGameState: b = new GetGameState(0, 0); break;

            case Types.GameState: b = new GameState(null, null, MatchStates.Tie, 0, 0); break;

            case Types.MakeMove: b = new MakeMove(0, null, null, MatchStates.Tie); break;

            case Types.ForfeitGame: b = new ForfeitGame(0); break;

            default: throw new NotImplementedException(type.ToString());
            }

            b.Deserialize(reader);

            return(b);
        }
Ejemplo n.º 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");
            }
        }