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 } }); }
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); }
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); }