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); } }
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"); } }