public async Task <ActionResult> CreatePrizePoolModal(CreatePrizePoolModel model) { if (!ModelState.IsValid) { model.Games = await GetPendingGames(); return(View(model)); } if (model.Type == Enums.PrizeType.Points) { model.Data = null; model.Data2 = null; } else if (model.Type == Enums.PrizeType.Crypto) { var isValid = true; if (string.IsNullOrEmpty(model.Data)) { // coin symbol missing ModelState.AddModelError("", "Coin symbol missing"); isValid = false; } if (!decimal.TryParse(model.Data2, out var parsedAmount) || parsedAmount < 0.00000001m) { // invalid amount ModelState.AddModelError("", "Invalid amount"); isValid = false; } if (!isValid) { model.Games = await GetPendingGames(); return(View(model)); } } var result = await PrizeWriter.CreatePrizePool(model); if (!ModelState.IsWriterResultValid(result)) { model.Games = await GetPendingGames(); return(View(model)); } return(CloseModalSuccess()); }
public async Task <IWriterResult> CreatePrizePool(CreatePrizePoolModel model) { var random = new Random(); var game = await GameReader.GetGame(model.GameId.Value); using (var context = DataContextFactory.CreateContext()) { var dateTimeNow = DateTime.UtcNow; var newPrizes = new List <Entity.Prize>(); var existingPixels = await context.Pixel .Where(x => x.GameId == model.GameId) .ToListAsync(); var existingPrizes = await context.Prize .Where(x => x.GameId == model.GameId && !x.IsClaimed) .ToListAsync(); if (existingPrizes.Any(x => x.Name.Equals(model.Name, StringComparison.OrdinalIgnoreCase))) { return(new WriterResult(false, "Prize pool name already exists")); } var totalPixels = game.Width * game.Height; var usedPixels = existingPixels.Count + existingPrizes.Count; var remainingPixels = totalPixels - usedPixels; if (model.Count > remainingPixels) { return(new WriterResult(false, "Not enough free pixels to distribute prize pool")); } while (newPrizes.Count < model.Count) { var locationX = random.Next(0, game.Width - 1); var locationY = random.Next(0, game.Height - 1); // Check Pixel rules var existingPixel = existingPixels.FirstOrDefault(x => x.X == locationX && x.Y == locationY); if (existingPixel != null) { if (existingPixel.Type == PixelType.Fixed) { continue; } if (model.MaxPoints > 0 && existingPixel.Points > model.MaxPoints) { continue; } } var existingPrize = existingPrizes.FirstOrDefault(x => x.X == locationX && x.Y == locationY); if (existingPrize != null) { continue; } // Check for duplicates if (newPrizes.Any(x => x.X == locationX && x.Y == locationY)) { continue; } newPrizes.Add(new Entity.Prize { X = locationX, Y = locationY, Type = model.Type, Name = model.Name, Description = model.Description, Points = model.Points, Data = model.Data, Data2 = model.Data2, Status = PrizeStatus.Unclaimed, IsClaimed = false, Timestamp = dateTimeNow, GameId = model.GameId.Value }); } context.Prize.AddRange(newPrizes); await context.SaveChangesAsync(); return(new WriterResult(true, "Successfully created all prizes")); } }