/// <summary> /// Call with a received message. If this message is not the current state's /// ValidReceives list, the connection will be disconnected. /// </summary> /// <param name="message">A received message</param> public void Received(IMessage message) { if (!_state.ValidReceives.Contains(message.TypeId)) { _disconnecter.Disconnect(); return; } _state.Received(this, message); }
public void Sent(NetworkStateContext context, IMessage message) { // The only valid send is FoundGame context.SetState(NetworkStateId.FoundGame); // Get the opponents connection. if (!_userRepo.TryGetSender(_state.Match.Opponent.Username, out var opponent)) { // Somehow the opponent is not logged in. _disconnecter.Disconnect(); return; } _state.SetMatchTimeoutCallback((s, e) => { // If the opponent has responded already, send a RejectGame to them. if (_state.Match.Opponent.AcceptedGame != MatchResponse.None) { opponent.Send(new BasicMessage(MessageTypeId.RejectGame)); } _sender.Send(new BasicMessage(MessageTypeId.GameExpired)); }); _state.StartMatchTimer(); }
public void Received(NetworkStateContext context, IMessage message) { // Only valid receive is MyGuess context.SetState(NetworkStateId.Waiting); var guess = ((MyGuessMessage)message).Position; var guessResult = _state.Match.Opponent.Board.Guess(guess); var id = guessResult switch { GuessResult.Miss => MessageTypeId.Miss, GuessResult.Hit => MessageTypeId.Hit, GuessResult.Sunk => MessageTypeId.Sunk, GuessResult.Win => MessageTypeId.YouWin, _ => throw new ArgumentOutOfRangeException() }; _sender.Send(new BasicMessage(id)); // Get the opponents connection. if (!_userRepo.TryGetSender(_state.Match.Opponent.Username, out var opponent)) { // Somehow the opponent is not logged in. _disconnecter.Disconnect(); return; } if (id == MessageTypeId.YouWin) { opponent.Send(new YouLoseMessage(guess)); return; } opponent.Send(new TheirGuessMessage(guess)); }
/// <summary> /// Asynchronously receive and parse data terminating if anything unexpected /// is received. /// </summary> public async Task StartReceivingAsync() { var reader = PipeReader.Create(_stream); _logger.LogInfo("Connected to " + _socket.RemoteEndPoint); while (true) { // Suspend this method until reader returns data. var result = await reader.ReadAsync(); // Parse contents until we run out of valid & complete messages. var position = _parser.Parse(result.Buffer); // Disconnect if we receive any invalid data. if (position == null) { break; } // Tell the reader how much data we evaluated so it does not return // data we have already seen. reader.AdvanceTo(position.Value, result.Buffer.End); } await reader.CompleteAsync(); _disconnecter.Disconnect(); }
public void Received(NetworkStateContext context, IMessage message) { // Get the opponents connection. if (!_userRepo.TryGetSender(_state.Match.Opponent.Username, out var opponent)) { // Somehow the opponent is not logged in. _disconnecter.Disconnect(); return; } _state.CancelMatchTimer(); // The player is rejecting the game. if (message.TypeId == MessageTypeId.RejectGame) { // Mark the player as accepting the game. _state.Match.Player.AcceptedGame = MatchResponse.Reject; // Update our state. context.SetState(NetworkStateId.WaitingForBoard); // Let the opponent know that the player has rejected the game. opponent.Send(new BasicMessage(MessageTypeId.RejectGame)); return; } // The only remaining valid message is AcceptGame. So mark the player as accept. _state.Match.Player.AcceptedGame = MatchResponse.Accept; // If the opponent has also sent AcceptGame, we let both know to start the game. if (_state.Match.Opponent.AcceptedGame == MatchResponse.Accept) { // Let both know that the game has been accepted. _sender.Send(new BasicMessage(MessageTypeId.AcceptGame)); opponent.Send(new BasicMessage(MessageTypeId.AcceptGame)); // Notify who goes first if (_state.Match.PlayerGoesFirst) { _sender.Send(new BasicMessage(MessageTypeId.AssignRed)); opponent.Send(new BasicMessage(MessageTypeId.AssignBlue)); } else { _sender.Send(new BasicMessage(MessageTypeId.AssignBlue)); opponent.Send(new BasicMessage(MessageTypeId.AssignRed)); } } }