public static async Task <IActionResult> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = null)] HttpRequest req, [CosmosDB( databaseName: "blazor-four-in-a-row", collectionName: "game-actions", ConnectionStringSetting = "CosmosDBConnection", CreateIfNotExists = true)] DocumentClient client, ILogger log) { Uri documentCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId: "blazor-four-in-a-row", collectionId: "game-actions"); var gameStateBuilder = new GameStateBuilder(); var currentGame = client.CreateDocumentQuery <GameAction>(documentCollectionUri) .Where(g => g.GameActionType == GameActionTypes.CreateGame) .OrderByDescending(g => g.CreatedOn) .AsEnumerable() .FirstOrDefault(); if (null != currentGame) { var gameActionsProvider = new GameActionsProvider(); var gameActions = gameActionsProvider.GetGameActions(client, currentGame.GameId); if (!gameActions.Any(g => g.GameActionType == GameActionTypes.CompleteGame || g.GameActionType == GameActionTypes.AbandonGame)) { //Check if game is active if (gameActions.Any(g => g.CreatedOn > DateTime.Now.AddMinutes(-1 * currentGame.GameSettings.GameAbandonmentMinutes))) { return(new OkObjectResult(gameStateBuilder.BuildGameState(gameActions))); } await client.CreateDocumentAsync(DocumentCollectionUri, new GameAction() { GameActionType = GameActionTypes.AbandonGame, GameId = currentGame.GameId, GameActionStatus = GameActionStatuses.Valid, }); } } var gameAction = await CreateNewGameAction(client); return(new OkObjectResult(gameStateBuilder.BuildGameState(new List <GameAction>() { gameAction }))); }
public static async Task <IActionResult> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = null)] HttpRequestMessage req, [CosmosDB( databaseName: "blazor-four-in-a-row", collectionName: "game-actions", ConnectionStringSetting = "CosmosDBConnection", CreateIfNotExists = true)] DocumentClient client, ILogger log) { var gamePlayer = await req.Content.ReadAsAsync <(string GameId, User User)> (); var gameStateBuilder = new GameStateBuilder(); var gameActionsProvider = new GameActionsProvider(); var gameActions = gameActionsProvider.GetGameActions(client, gamePlayer.GameId); var gameState = gameStateBuilder.BuildGameState(gameActions); var gameStateManager = new GameStateManager(); if (gameStateManager.UserHasJoinedGame(gameState, gamePlayer.User)) { return(new ConflictResult()); } var teamToJoin = DetermineWhichTeamToJoin(gameState); teamToJoin.Users.Add(gamePlayer.User); await client.CreateDocumentAsync(DocumentCollectionUri, new GameAction() { GameActionStatus = GameActionStatuses.Valid, GameActionType = GameActionTypes.JoinGame, GameId = gamePlayer.GameId, User = gamePlayer.User, Team = teamToJoin }); return(new OkObjectResult(teamToJoin)); }
public static async Task RunAsync([CosmosDBTrigger( databaseName: "blazor-four-in-a-row", collectionName: "game-actions", ConnectionStringSetting = "CosmosDBConnection", LeaseCollectionName = "leases", CreateLeaseCollectionIfNotExists = true, FeedPollDelay = 200)] IReadOnlyList <Document> input, [CosmosDB( databaseName: "blazor-four-in-a-row", collectionName: "game-actions", ConnectionStringSetting = "CosmosDBConnection", CreateIfNotExists = true)] DocumentClient client, [SignalR(HubName = "gameUpdates")] IAsyncCollector <SignalRMessage> signalRMessages, ILogger log) { if (input != null && input.Count > 0) { log.LogInformation("GameActions modified " + input.Count); var gameStateBuilder = new GameStateBuilder(); var gameActionsProvider = new GameActionsProvider(); var gameStateManager = new GameStateManager(); var updatedGameIds = new List <string>(); foreach (var document in input) { GameAction gameAction = (dynamic)document; if (!updatedGameIds.Contains(gameAction.GameId)) { updatedGameIds.Add(gameAction.GameId); } if (gameAction.GameActionStatus != GameActionStatuses.AwaitingValidation) { log.LogInformation($"Game Action {gameAction.Id} does not require validation. GameActionType: {gameAction.GameActionType}"); continue; } log.LogInformation($"Validating Game Action {gameAction.Id}."); var gameActions = gameActionsProvider.GetGameActions(client, gameAction.GameId); var gameState = gameStateBuilder.BuildGameState(gameActions); gameAction.GameActionStatus = gameStateManager.ValidateGameColumnAction(gameState, gameAction.GameCell.Column); ValidateGameStartLock(gameState, gameAction); ValidateNextActionLock(gameState, gameAction); log.LogInformation( $"Game Action {gameAction.Id}'s status is {Enum.GetName(typeof(GameActionStatuses), gameAction.GameActionStatus)}."); if (gameAction.GameActionStatus == GameActionStatuses.Valid) { foreach (var row in gameState.GameCells) { var gameCell = row[gameAction.GameCell.Column]; if (null == gameCell.Team) { gameAction.GameCell.Row = gameCell.Row; gameCell.Team = gameAction.Team; gameCell.User = gameAction.User; break; } } } await client.UpsertDocumentAsync(DocumentCollectionUri, gameAction); if (null == gameState.GameResult) { var gameResult = gameStateManager.CheckForGameCompletion(gameState); if (null != gameResult) { var gameBuilder = new GameBuilder(); var newGameAction = gameBuilder.BuildNewGame(client); await client.CreateDocumentAsync(DocumentCollectionUri, new GameAction() { GameId = gameAction.GameId, GameActionStatus = GameActionStatuses.Valid, GameActionType = GameActionTypes.CompleteGame, Team = gameResult.WinningTeam, NextGameId = newGameAction.GameId }); await client.CreateDocumentAsync(DocumentCollectionUri, newGameAction); } } } foreach (var gameId in updatedGameIds) { if (string.IsNullOrEmpty(gameId)) { continue; } var gameActions = gameActionsProvider.GetGameActions(client, gameId); await signalRMessages.AddAsync( new SignalRMessage { Target = "game-state-update", Arguments = new object[] { gameStateBuilder.BuildGameState(gameActions) } }); } //TODO: Task.WhenAll these awaits? } }