private async Task <IEnumerable <UserResult> > changeUserStat(InventoryItemDetails item, ItemEffect effect, User activeUser)
        {
            ChangeUserStatEffectArgument arg = (ChangeUserStatEffectArgument)effect.EffectParameters;

            switch (arg.Stat)
            {
            case UserStat.Cash:
                await UserDomain.ChangeUserCash(arg.Amount, activeUser);

                break;

            default:
                break;
            }

            return(new List <UserResult>
            {
                new UserResult
                {
                    ChangedStat = arg.Stat,
                    StatChangeAmount = arg.Amount
                }
            });
        }
Exemple #2
0
        public async Task <bool> CreateRandomEvent(User recipient, User activeDev)
        {
            RandomEventNotification notify = new RandomEventNotification();

            var eventDefs = await RandomEvents.GetEventDefinitions();

            if (eventDefs.Count() == 0)
            {
                return(false);
            }

            var definition = eventDefs.SelectRandom();

            using (var trans = TransactionScopeFactory.Create())
            {
                //generate or take items
                if (definition.ItemTransferMaxQuantity.HasValue && definition.ItemTransferMinQuantity.HasValue)
                {
                    if (definition.GiveItemEvent && definition.SpecificItemTypes?.Count > 0)
                    {
                        int qtyMoved = 0;
                        foreach (var item in definition.SpecificItemTypes)
                        {
                            if (qtyMoved >= definition.ItemTransferMaxQuantity)
                            {
                                break;
                            }

                            int itemQty = Utilities.Extensions.Random.Next(definition.ItemTransferMinQuantity.Value, definition.ItemTransferMaxQuantity.Value - qtyMoved);
                            qtyMoved += itemQty;
                            var newItems = (await InventoryDomain.GenerateItems(item.Id, recipient.Id, itemQty)).ToList();
                            newItems.AddRange(notify.AddedItems);
                            notify.AddedItems = newItems;
                        }
                    }
                    else if (definition.SpecificItemTypes?.Count > 0) //take stuff away!
                    {
                        var currentItems = await InventoryDomain.GetInventory(recipient);

                        int qtyMoved = 0;
                        foreach (var item in definition.SpecificItemTypes)
                        {
                            if (qtyMoved >= definition.ItemTransferMaxQuantity)
                            {
                                break;
                            }

                            var foundItems = currentItems.Where(i => i.ItemTypeId == item.Id);
                            if (foundItems.Count() != 0)
                            {
                                int itemQty = Utilities.Extensions.Random.Next(definition.ItemTransferMinQuantity.Value, Math.Min(foundItems.Count(), definition.ItemTransferMaxQuantity.Value - qtyMoved));
                                qtyMoved += itemQty;
                                var selectedItems = foundItems.Take(itemQty).ToList();
                                await Task.WhenAll(selectedItems.Select(i => InventoryDomain.DiscardItem(i.Id, recipient)));

                                var lostItems = await InventoryDomain.GetItemDetails(selectedItems.Select(i => i.Id).ToArray());

                                lostItems.AddRange(notify.RemovedItems);
                                notify.RemovedItems = lostItems;
                            }
                        }
                    }
                }

                if (definition.CashDeltaMax.HasValue && definition.CashDeltaMin.HasValue)
                {
                    int changeMin = definition.CashDeltaMin.Value;
                    int changeMax = definition.CashDeltaMax.Value;
                    if (changeMin < 0)                                        //stealing event, try not to steal too much from them
                    {
                        changeMin = Math.Max(recipient.Cash / -2, changeMin); //max because they're negatives
                        if (changeMax < changeMin)
                        {
                            changeMax = changeMin;
                        }
                    }
                    int cashDelta = Utilities.Extensions.Random.Next(changeMin, changeMax);
                    await UserDomain.ChangeUserCash(cashDelta, recipient);

                    notify.CashChangedAmount = cashDelta;
                }
                notify.ImagePath = definition.ImagePath;
                notify.AlertText = definition.DisplayMessage;

                trans.Complete();
            }
            await HubContext.Clients.User(recipient.Username).ReceiveNotification(notify);

            //todo if cant deliver now, deliver later (put in DB, return on login)

            return(true);
        }
Exemple #3
0
        public async Task <GameScoreResult> SubmitScore(User activeUser, GameType gameId, int score, string scoreToken)
        {
            var key = await GameRepo.GetGameSigningKey(gameId, activeUser.Id);

            GameRepo.DeleteGameSigningKey(gameId, activeUser.Id);

            bool            succeeded   = false;
            ClaimsPrincipal token       = null;
            bool            validClaims = false;

            if (key != null)
            {
                token = JwtProvider.CrackJwt(scoreToken, key);

                validClaims  = token?.Claims.Where(c => c.Type == "g").FirstOrDefault().Value == ((int)gameId).ToString();//don't forget about GUS
                validClaims &= token?.Claims.Where(c => c.Type == "u").FirstOrDefault().Value == activeUser.Username;
                validClaims &= token?.Claims.Where(c => c.Type == "s").FirstOrDefault().Value == score.ToString();
            }
            if (!validClaims)
            {
                throw new CritterException("Sorry, we couldn't record this score! Something went wrong.",
                                           $"Potential cheating: user {activeUser.Id} at game {gameId} with score {score} and token: {scoreToken}",
                                           System.Net.HttpStatusCode.BadRequest, LogLevel.Warning);
            }

            GameScoreResult result = new GameScoreResult();

            using (var trans = TransactionScopeFactory.Create())
            {
                GameConfig gameCfg = (await ConfigRepo.RetrieveGamesConfigByIds(true, gameId)).FirstOrDefault();
                if (gameCfg == null)
                {
                    throw new CritterException("Sorry, we couldn't record this score because this game doesn't exist!",
                                               $"Invalid game ID entered by user {activeUser.Id} for game {gameId} with score {score} and token: {scoreToken}",
                                               System.Net.HttpStatusCode.NotFound, LogLevel.Error);
                }

                var previousSubmissions = await GameRepo.GetScoreSubmissionCount(gameId, activeUser.Id);

                if (gameCfg.DailyCashCountCap <= previousSubmissions)
                {
                    throw new CritterException("Sorry, we couldn't record this score, you have submitted your score too many times for this game today!",
                                               gameCfg.DailyCashCountCap < previousSubmissions ? $"User {activeUser.Id} over-submitted at game {gameId} with token: {scoreToken} somehow" : null,
                                               System.Net.HttpStatusCode.TooManyRequests, gameCfg.DailyCashCountCap < previousSubmissions ? LogLevel.Error : LogLevel.Debug);
                }

                bool success = await GameRepo.UpsertGameScoreForLeaderboard(activeUser.Id, gameId, score);

                if (gameCfg.ScoreToCashFactor.HasValue)
                {
                    int cashVal = (int)((gameCfg.ScoreToCashFactor ?? 1) * score);
                    cashVal        = Math.Min(cashVal, gameCfg.CashCap ?? Int32.MaxValue);
                    result.CashWon = cashVal;
                    activeUser     = await UserDomain.ChangeUserCash(cashVal, activeUser);
                }
                result.RemainingSubmissions = (gameCfg.DailyCashCountCap ?? 100) - (previousSubmissions + 1);
                await GameRepo.SetScoreSubmissionCount(gameId, activeUser.Id, previousSubmissions + 1);

                trans.Complete();
                succeeded = true;
            }
            if (!succeeded)
            {
                GameRepo.SaveGameSigningKey(gameId, activeUser.Id, key); //let em try again if we Db fail
                throw new CritterException("We failed to record your score. Please try and submit again! Contact an admin if this continues.",
                                           $"Failed to record good score for user {activeUser.Id} at game {gameId} with score {score} and token: {scoreToken}",
                                           System.Net.HttpStatusCode.InternalServerError, LogLevel.Error);
            }
            return(result);
        }