public async Task <Result <IGameResult, ErrorCode> > BonusGame(RequestContext <BonusArgs> requestContext) { if (!gameModules.TryGetModule(requestContext.GameKey, out IGameModule module)) { return(ErrorCode.InvalidGame); } using (logger.BeginScope(new Dictionary <string, object> { ["SessionKey"] = requestContext.UserSession.SessionKey, ["UserId"] = requestContext.UserSession.UserId, ["GameKey"] = requestContext.GameKey, ["Platform"] = requestContext.Platform, ["BonusParams"] = requestContext.Parameters.Param })) { try { var bonus = await bonusService.GetUnfinishBonus(requestContext.UserSession, requestContext.Game.Id); if (bonus == null) { logger.LogWarning("User play bonus game but no bonus found."); return(ErrorCode.NonexistenceBonus); } var level = await userService.GetLevel(requestContext.UserGameKey); logger.LogInformation("User play bonus game with level {Level}, id {BonusId}", level, bonus.Guid); var bonusGameResult = module.ExecuteBonus(level, bonus, requestContext); if (bonusGameResult.IsError) { logger.LogWarning("Execute bonus got error {Error}", bonusGameResult.Error); return(bonusGameResult.Error); } var result = bonusGameResult.Value; if (result.TransactionType == GameTransactionType.None) { throw new InvalidGameModuleImplementation(requestContext.GameKey, $"Must set transaction type to bonus result for ExecuteBonus"); } if (!result.IsCompleted && result.Bonus == null) { throw new InvalidGameModuleImplementation(requestContext.GameKey, "If bonus is not completed, the BonusResult.Bonus can not be null."); } var transaction = await payoutService.GetGameTransaction(requestContext.UserGameKey, result.TransactionType); result.TransactionId = transaction.Id; result.UniqueID = result.TransactionId.ToString(); result.DateTimeUtc = transaction.DateTimeUtc; result.RoundId = bonus.RoundId; if (result.IsCompleted) { await bonusService.RemoveBonus(requestContext.UserSession, bonus); await userService.UpdateGameState(requestContext, UserGameState.ForNormal(result.RoundId)); } else { bonus.Data = result.Bonus.ToByteArray(); await bonusService.UpdateBonus(requestContext.UserSession, bonus); } await payoutService.PayoutToUser(requestContext, result, new BonusExtraInfo { BetId = bonus.BetReference, RoundId = bonus.RoundId }, result.IsCompleted); await TrySaveGameHistory(requestContext, result); //if (result.IsCompleted) //{ // await payoutService.NotifyEndGame(requestContext, result); //} return(result); } catch (Exception ex) { logger.LogError(ex, ex.Message); } return(ErrorCode.InternalError); } }