public async Task DealGame(DealGameRequest request) { async Task InvokeOnDealGameResponse(DealGameResponse resp) { _logger.LogInformation("Sending Response: {}", resp); await Clients.Caller.SendAsync("OnDealGameResponse", resp); } try { await _gameService.DealGameAsync(request, InvokeOnDealGameResponse); } catch (Exception ex) { _logger.LogError(ex, nameof(JoinGame)); await InvokeOnDealGameResponse(new DealGameResponse() { ErrorMessage = $"{ex.GetType()}: {ex.Message}" }); } }
public async Task DealGameAsync(DealGameRequest request, Func <DealGameResponse, Task> responseHandler) { _logger.LogInformation("DealGame {}", request); var resp = new DealGameResponse() { RequestId = request.RequestId }; try { if (!await AcquireGameLock(request.GameId, request.RequestId, TimeSpan.FromSeconds(30))) { resp.ErrorMessage = "Timed out while acquiring game lock"; await responseHandler(resp); return; } if (request.RequestType == DealGameRequest.RequestTypes.DeleteGame) { (resp.IsSuccess, resp.ErrorMessage) = await DeleteGameIfFinished(request.GameId, request.PlayerId); await responseHandler(resp); return; } var gameState = await _dbContext.GameStates .FirstOrDefaultAsync(x => x.GameId == request.GameId); if (gameState == null) { resp.ErrorMessage = "GameId not found"; await responseHandler(resp); return; } var gameEngine = new GameEngine(_loggerProvider, _dbContext, _cardRepo); gameEngine.GameState = gameState; if (gameEngine.GameState.IsFinished) { resp.ErrorMessage = "Game is finished"; await responseHandler(resp); return; } if (gameEngine.GameState.PlayerId != request.PlayerId) { resp.ErrorMessage = "Only dealer can initiate this request"; await responseHandler(resp); return; } if (request.RequestType == DealGameRequest.RequestTypes.DealCard) { var(success, err, updatedPlayerStates) = await gameEngine.DealPlayerCards(); resp.IsSuccess = success; resp.ErrorMessage = err; await responseHandler(resp); if (resp.IsSuccess) { foreach (var playerState in updatedPlayerStates) { InvokeOnPlayerUpdate(MakePlayerUpdateResponse(playerState)); } InvokeOnGameUpdate(MakeGameUpdateResponse(gameEngine.GameState)); } } else if (request.RequestType == DealGameRequest.RequestTypes.LockTrading || request.RequestType == DealGameRequest.RequestTypes.UnlockTrading) { var locked = request.RequestType == DealGameRequest.RequestTypes.LockTrading ? true : false; (resp.IsSuccess, resp.ErrorMessage) = await gameEngine.LockTrading(locked); await responseHandler(resp); if (resp.IsSuccess) { InvokeOnGameUpdate(MakeGameUpdateResponse(gameEngine.GameState)); } } else if (request.RequestType == DealGameRequest.RequestTypes.FinishGame) { (resp.IsSuccess, resp.ErrorMessage) = await gameEngine.FinishGame(); await responseHandler(resp); if (resp.IsSuccess) { InvokeOnGameUpdate(MakeGameUpdateResponse(gameEngine.GameState)); } } else { resp.ErrorMessage = "Unknown deal request type"; await responseHandler(resp); } } finally { ReleaseGameLock(request.GameId, request.RequestId); } }