Beispiel #1
0
        public virtual async Task StartAsync(Game.StartCommand command, CancellationToken cancellationToken = default)
        {
            var(session, id) = command;
            var context = CommandContext.GetCurrent();

            var user = await AuthService.GetUserAsync(session, cancellationToken);

            user = user.MustBeAuthenticated();
            var userId = long.Parse(user.Id);

            await using var dbContext = await CreateCommandDbContextAsync(cancellationToken);

            var dbGame = await GetDbGame(dbContext, id, cancellationToken);

            var game   = dbGame.ToModel();
            var engine = GameEngines[game.EngineId];

            if (game.Stage != GameStage.New)
            {
                throw new InvalidOperationException("Game has already been started.");
            }
            if (game.UserId != userId && !engine.AutoStart)
            {
                throw new InvalidOperationException("Only the creator of the game can start it.");
            }
            if (game.Players.Count < engine.MinPlayerCount)
            {
                throw new InvalidOperationException(
                          $"{engine.MinPlayerCount - game.Players.Count} more player(s) must join to start the game.");
            }
            if (game.Players.Count > engine.MaxPlayerCount)
            {
                throw new InvalidOperationException(
                          $"Too many players: {engine.MaxPlayerCount - game.Players.Count} player(s) must leave to start the game.");
            }

            context.Operation().Items.Set(game.Stage); // Saving prev. stage
            var now = Clock.Now;

            game = game with {
                StartedAt  = now,
                LastMoveAt = now,
                Stage      = GameStage.Playing,
            };
            game = GameEngines[game.EngineId].Start(game);
            dbGame.UpdateFrom(game);
            await dbContext.SaveChangesAsync(cancellationToken);

            context.Operation().Items.Set(game);
        }
Beispiel #2
0
 public Task Start([FromBody] Game.StartCommand command, CancellationToken cancellationToken = default)
 {
     command.UseDefaultSession(SessionResolver);
     return(Games.Start(command, cancellationToken));
 }