public async Task <ActionResult <int> > ImportChallengeAsync(ChallengeImportDto dto) { _ = dto ?? throw new ArgumentNullException(nameof(dto)); try { return(await _challengeService.ImportChallengeAsync(dto)); } catch (HttpRequestException e) { return(BadRequest(e.Message)); } catch (InvalidOperationException e) { return(BadRequest(e.Message)); } }
public async Task <int> ImportChallengeAsync(ChallengeImportDto dto, int gameId) { _ = dto ?? throw new ArgumentNullException(nameof(dto)); (GeoGuessrChallenge challenge, IList <GeoGuessrChallengeResult> results) = await _geoGuessrService.ImportChallengeAsync(dto.GeoGuessrId); var locations = new List <Location>(); HttpClient googleClient = _clientFactory.CreateClient("google"); for (int i = 0; i < results[0].Game.Rounds.Count; i++) { GeoGuessrRound round = results[0].Game.Rounds[i]; string query = $"geocode/json?latlng={round.Lat.ToString(CultureInfo.InvariantCulture)},{round.Lng.ToString(CultureInfo.InvariantCulture)}&key={_options.GoogleApiKey}"; GoogleGeocode? geocode = await googleClient.GetFromJsonAsync <GoogleGeocode>(query); if (geocode?.Results?.Count > 0) { GoogleGeocodeResult result = geocode.Results[0]; var location = new Location() { DisplayName = result.FormattedAddress, Locality = result.AddressComponents.FirstOrDefault(x => x.Types.Contains("locality"))?.Name, AdministrativeAreaLevel2 = result.AddressComponents.FirstOrDefault(x => x.Types.Contains("administrative_area_level_2"))?.Name, AdministrativeAreaLevel1 = result.AddressComponents.FirstOrDefault(x => x.Types.Contains("administrative_area_level_1"))?.Name, Country = result.AddressComponents.FirstOrDefault(x => x.Types.Contains("country"))?.Name, Latitude = round.Lat, Longitude = round.Lng, RoundNumber = i + 1, }; locations.Add(location); } } var playerScores = new List <PlayerScore>(); foreach (GeoGuessrPlayer geoChallengeGamePlayer in results.Select(g => g.Game.Player)) { bool isMainPlayer = true; Player player = await _context.Players.FindAsync(geoChallengeGamePlayer.Id) ?? new Player { Id = geoChallengeGamePlayer.Id, Name = geoChallengeGamePlayer.Nick, }; if (player.AssociatedPlayerId is not null) { player = (await _context.Players.FindAsync(player.AssociatedPlayerId)) !; isMainPlayer = false; } // Update icon in order to have the most recent one. if (!string.IsNullOrWhiteSpace(geoChallengeGamePlayer.Pin.Url.ToString())) { player.IconUrl = new Uri($"https://www.geoguessr.com/images/auto/144/144/ce/0/plain/{geoChallengeGamePlayer.Pin.Url}"); } else { player.IconUrl = Constants.BaseAvatarUrl; } var playerScore = new PlayerScore { PlayerId = player.Id, Player = player, PlayerGuesses = geoChallengeGamePlayer.Guesses.Select((p, i) => new PlayerGuess { Score = p.RoundScoreInPoints, RoundNumber = i + 1, Time = p.Time, TimedOut = p.TimedOut, TimedOutWithGuess = p.TimedOutWithGuess, Distance = p.DistanceInMeters, }).ToList(), }; if (isMainPlayer && playerScores.Any(ps => ps.PlayerId == playerScore.PlayerId)) { playerScores.RemoveAll(ps => ps.PlayerId == playerScore.PlayerId); } if (!playerScores.Any(ps => ps.PlayerId == playerScore.PlayerId)) { playerScores.Add(playerScore); } } Map map = await _context.Maps.FindAsync(challenge.Map.Id) ?? new Map { Id = challenge.Map.Id, Name = challenge.Map.Name, }; Player?creator = await _context.Players.FindAsync(challenge.Creator.Id); if (creator is null) { throw new InvalidOperationException($"Cannot import challenges created by {challenge.Creator.Nick}."); } var newChallenge = new Challenge() { GameId = gameId, MapId = map.Id, Map = map, GeoGuessrId = dto.GeoGuessrId, PlayerScores = playerScores, TimeLimit = challenge.Challenge.TimeLimit, Locations = locations, CreatorId = creator.Id, UpdatedAt = DateTime.UtcNow, }; Challenge?existingChallenge = await _context .Challenges .Include(c => c.Map) .Include(c => c.PlayerScores).ThenInclude(c => c.PlayerGuesses) .Include(c => c.Locations) .SingleOrDefaultAsync(c => c.GeoGuessrId == dto.GeoGuessrId); int challengeId; if (existingChallenge is not null) { if (existingChallenge.GameId != gameId) { throw new InvalidOperationException($"The challenge with GeoGuessr Id '{dto.GeoGuessrId}' is already linked to a game and cannot be updated."); } if (!dto.OverrideData) { throw new InvalidOperationException($"The challenge with GeoGuessr Id '{dto.GeoGuessrId}' already exists."); } existingChallenge.PlayerScores = newChallenge.PlayerScores; existingChallenge.MapId = newChallenge.MapId; existingChallenge.Map = newChallenge.Map; existingChallenge.TimeLimit = newChallenge.TimeLimit; existingChallenge.Locations = newChallenge.Locations; existingChallenge.CreatorId = newChallenge.CreatorId; existingChallenge.UpdatedAt = newChallenge.UpdatedAt; challengeId = existingChallenge.Id; await _context.SaveChangesAsync(); } else { EntityEntry <Challenge>?newChallengeEntity = _context.Challenges.Add(newChallenge); await _context.SaveChangesAsync(); challengeId = newChallengeEntity.Entity.Id; } _cache.Remove(CacheKeys.PlayerServiceGetAllAsync); _cache.Remove(CacheKeys.MapServiceGetAllAsync); return(challengeId); }
public Task <int> ImportChallengeAsync(ChallengeImportDto dto) { return(ImportChallengeAsync(dto, -1)); }