예제 #1
0
 public void SetPlayerWaitMsg(UserGameState _state, GIPEndPoint _players)
 {
     SetPlayerWaitMsg(_state, new List <GIPEndPoint> ()
     {
         _players
     });
 }
예제 #2
0
 public static UserGameState Map(GameState state)
 {
     if (state.Type == GameStateType.SlotStateNormal)
     {
         return(UserGameState.ForNormal(state.LastRoundId ?? 0));
     }
     return(UserGameState.ForBonus(state.LastRoundId ?? 0));
 }
예제 #3
0
 public void SetPlayerWaitMsg(UserGameState _state, List <GIPEndPoint> _players = null)
 {
     if (_players == null)
     {
         _players = players;
     }
     // if (_state == UserGameState.waitMsg) lastWait = _players;
     foreach (var _ip in _players)
     {
         User user = GlobalData.GetUser(_ip);
         user.gameInfo.gameState = _state;
     }
 }
예제 #4
0
        private async Task <UserGameState> GetGameStateFromCache(string key)
        {
            var gameState = await cache.GetAsync <UserGameState>(key);

            if (gameState == null)
            {
                gameState = UserGameState.InitialState();
                await cache.SetAsync(key, gameState, new DistributedCacheEntryOptions
                {
                    SlidingExpiration = TimeSpan.FromMinutes(5)
                });
            }
            return(gameState);
        }
예제 #5
0
        public async Task <bool> UpdateGameState <T>(RequestContext <T> requestContext, UserGameState userGameState)
        {
            try
            {
                if (requestContext.UserSession.IsFunPlay)
                {
                    await cache.SetAsync(requestContext.SessionKey, userGameState, new DistributedCacheEntryOptions
                    {
                        SlidingExpiration = TimeSpan.FromMinutes(5)
                    });

                    return(true);
                }
                else
                {
                    using (var db = databaseManager.GetWritableDatabase())
                    {
                        var state = db.GameStates.Find(requestContext.UserSession.User.Id, requestContext.Game.Id);
                        if (state == null)
                        {
                            return(false);
                        }
                        state.LastRoundId = userGameState.LastRoundId;
                        state.Type        = userGameState.Type;
                        db.GameStates.Update(state);
                        return(await db.SaveChangesAsync() > 0);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogRequestContext(requestContext, LogLevel.Error);
                logger.LogError(ex, ex.Message);
                return(false);
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        public async Task <Result <IGameResult, ErrorCode> > Spin(RequestContext <SpinArgs> requestContext)
        {
            using (logger.BeginScope(new Dictionary <string, object>
            {
                ["SessionKey"] = requestContext.UserSession.SessionKey,
                ["UserId"] = requestContext.UserSession.UserId,
                ["GameKey"] = requestContext.GameKey,
                ["Platform"] = requestContext.Platform,
                ["BettingLines"] = requestContext.Parameters.BettingLines,
                ["LineBet"] = requestContext.Parameters.LineBet,
                ["Multiplier"] = requestContext.Parameters.Multiplier
            }))
            {
                var        module      = gameModules.GetModule(requestContext.GameKey);
                var        userSession = requestContext.UserSession;
                SpinResult result      = null;
                var        level       = await userService.GetLevel(requestContext.UserGameKey);

                try
                {
                    var transaction = await transactionService.GenerateGameTransactionId(requestContext.UserGameKey, GameTransactionType.Spin);

                    requestContext.GameTransaction = transaction;

                    var roundId = await transactionService.GenerateAutoNumber(CounterType.RoundId);

                    requestContext.CurrentRound = roundId;

                    var lastSpinData = await userService.GetLastSpinData(userSession, requestContext.Game);

                    var totalBet = module.CalculateTotalBet(lastSpinData, requestContext);

                    logger.LogInformation("User spin on level {Level}, trx id {GameTransactionId}, round {CurrentRoundId}, total bet {TotalBet}", level, transaction.Id, roundId, totalBet);

                    var deductBet = await payoutService.DeductBetFromWallet(requestContext, totalBet);

                    // TODO we should check the wallet result if it's success

                    var spinResult = module.ExecuteSpin(level, lastSpinData, requestContext);
                    if (spinResult.IsError)
                    {
                        return(spinResult.Error);
                    }

                    result               = spinResult.Value;
                    result.Bet           = totalBet;
                    result.RoundId       = roundId;
                    result.TransactionId = transaction.Id;
                    result.UniqueID      = result.TransactionId.ToString();
                    result.DateTimeUtc   = transaction.DateTimeUtc;
                    result.ExchangeRate  = deductBet.ExchangeRate;
                    result.Balance       = Balance.Create(deductBet.Balance);

                    if (result.HasBonus)
                    {
                        logger.LogInformation("User got bonus");
                        var bonusCreated = module.CreateBonus(result);
                        if (bonusCreated.IsError)
                        {
                            logger.LogWarning("Create bonus got error {Error} with {SpinResult}", bonusCreated.Error, JsonHelper.FullString(result));
                            return(ErrorCode.InternalError);
                        }

                        var bonus = bonusCreated.Value;
                        bonus.SpinTransactionId = transaction.Id;
                        bonus.GameResult        = result;
                        var entity = new BonusEntity
                        {
                            UserId       = userSession.UserId,
                            GameId       = requestContext.Game.Id,
                            Guid         = bonus.Guid.ToString("N"),
                            Data         = bonus.ToByteArray(),
                            BonusType    = bonus.GetType().Name,
                            Version      = 3,
                            IsOptional   = bonus.IsOptional,
                            IsStarted    = bonus.IsStarted,
                            RoundId      = roundId,
                            BetReference = deductBet.BetReference
                        };
                        await bonusService.UpdateBonus(userSession, entity);

                        await userService.UpdateGameState(requestContext, UserGameState.ForBonus(roundId));
                    }
                    else
                    {
                        await userService.UpdateGameState(requestContext, UserGameState.ForNormal(roundId));
                    }

                    var paied = await payoutService.PayoutToUser(requestContext, result, new BonusExtraInfo { RoundId = roundId, BetId = deductBet.BetReference }, !result.HasBonus, deductBet.Guid);

                    result.ExchangeRate = deductBet.ExchangeRate;
                    result.Balance      = Balance.Create(paied.Balance);

                    await transactionService.ProfileSpinBet(requestContext);

                    await userService.UpdateLastSpinData(userSession, requestContext.Game, result);

                    if (!userSession.IsFunPlay)
                    {
                        await userService.UpdateUserGameData(new UserGameData
                        {
                            UserId = userSession.UserId,
                            GameId = requestContext.Game.Id,
                            Bet    = requestContext.Parameters.LineBet,
                            Lines  = requestContext.Game.Lines,
                        });
                    }
                }
                catch (InsufficientBalanceException ex)
                {
                    logger.LogInformation(ex, ex.Message);
                    return(ErrorCode.InsufficientCredit);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, ex.Message);
                    throw;
                }
                finally
                {
                    await TrySaveGameHistory(requestContext, result);
                }
                return(result);
            }
        }