public async Task <string> HandleAsync(NewGameCommand command, CancellationToken cancellationToken)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            using (var session = _documentStore.OpenAsyncSession())
            {
                var gameId = _guidProvider.GenerateGuidString();
                var game   = _gameGenerator.GenerateGame(command.TableRows, command.TableColumns, command.MineCount);

                var player1MarkTable       = _playerMarksGenerator.GenerateDefaultPlayerMarksTable(command.TableRows, command.TableColumns);
                var player1MarksDocumentId = session.GetPlayerMarksDocumentId(gameId, command.HostPlayerId);
                var player1MarksDocument   = new PlayerMarks {
                    Marks = player1MarkTable, Id = player1MarksDocumentId
                };

                // TODO: Validate that the invited player's Id is not the same as the host's Id.
                game.Id = _documentStore.GetPrefixedDocumentId <Game>(gameId);
                game.InvitedPlayerId     = string.IsNullOrWhiteSpace(command.InvitedPlayerId) ? null : command.InvitedPlayerId;
                game.Player1.PlayerId    = command.HostPlayerId;
                game.Player1.DisplayName = command.HostPlayerDisplayName;

                await session.StoreAsync(game, cancellationToken).ConfigureAwait(false);

                await session.StoreAsync(player1MarksDocument, cancellationToken).ConfigureAwait(false);

                await session.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                return(gameId);
            }
        }
Exemple #2
0
        public async Task HandleAsync(JoinGameCommand command, CancellationToken cancellationToken)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                var player2Id = command.PlayerId;

                var game = await session.LoadGameAsync(command.GameId, cancellationToken).ConfigureAwait(false);

                var changeVector = session.Advanced.GetChangeVectorFor(game);

                if (game == null)
                {
                    throw new GameNotFoundException();
                }

                if ((game.InvitedPlayerId != null && game.InvitedPlayerId != player2Id) || game.Player2.PlayerId != null || game.Player1.PlayerId == player2Id)
                {
                    throw new ActionNotAllowedException("You are not allowed to join the requested game.");
                }

                var player2MarkTable       = _playerMarksGenerator.GenerateDefaultPlayerMarksTable(game.Rows, game.Columns);
                var player2MarksDocumentId = session.GetPlayerMarksDocumentId(command.GameId, command.PlayerId);
                var player2MarksDocument   = new PlayerMarks {
                    Marks = player2MarkTable, Id = player2MarksDocumentId
                };

                game.UtcDateTimeStarted  = _dateTimeProvider.GetUtcDateTime();
                game.Status              = GameStatus.InProgress;
                game.Player2.PlayerId    = player2Id;
                game.Player2.DisplayName = command.PlayerDisplayName;

                // TODO: Investigate what exception is thrown when a concurrent update occurs (because of the changevector) and rethrow an appropriate custom exception
                await session.StoreAsync(game, changeVector, game.Id, cancellationToken).ConfigureAwait(false);

                await session.StoreAsync(player2MarksDocument, cancellationToken).ConfigureAwait(false);

                await session.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
            }
        }