public virtual async Task Move(Game.MoveCommand command, CancellationToken cancellationToken = default) { var(session, id, move) = command; var context = CommandContext.GetCurrent(); var user = await AuthService.GetUser(session, cancellationToken); user = user.MustBeAuthenticated(); var userId = long.Parse(user.Id); await using var dbContext = await CreateCommandDbContext(cancellationToken); var dbGame = await GetDbGame(dbContext, id, cancellationToken); var game = dbGame.ToModel(); var engine = GameEngines[game.EngineId]; if (game.Stage != GameStage.Playing) { throw new InvalidOperationException("Game has already ended or hasn't started yet."); } var player = game.Players.SingleOrDefault(p => p.UserId == userId); if (player == null) { throw new InvalidOperationException("You aren't a participant of this game."); } var playerIndex = game.Players.IndexOf(player); var now = Clock.Now; move = move with { PlayerIndex = playerIndex, Time = now, }; context.Operation().Items.Set(Box.New(game.Stage)); // Saving prev. stage game = engine.Move(game, move) with { LastMoveAt = now }; if (game.Stage == GameStage.Ended) { game = game with { EndedAt = now } } ; dbGame.UpdateFrom(game); await dbContext.SaveChangesAsync(cancellationToken); context.Operation().Items.Set(game); }
public Task Move([FromBody] Game.MoveCommand command, CancellationToken cancellationToken = default) { command.UseDefaultSession(SessionResolver); return(Games.Move(command, cancellationToken)); }