private void CreateRaidsFromScanResult(PogoAfoMapping map, PogoAfoResult pogoAfoResult, long channel) { var raidParticipationCollection = DB.GetCollection <RaidParticipation>(); var raidsList = raidParticipationCollection.FindAll().ToArray(); foreach (var entry in pogoAfoResult.raids ?? new Dictionary <string, PogoAfoRaidInfo>()) { // TODO: Should be part of the query already, why ask for items then discard them? if (entry.Value.raid_level < 4 && !entry.Value.ex_trigger) { _log.Trace($"{SourceID} - Ignoring raid {entry.Key} @{entry.Value.raid_battle} level: {entry.Value.raid_level} / trigger: {entry.Value.ex_trigger} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); continue; } if (map.NorthEastCorner != null && map.SouthWestCorner != null && entry.Value.latitude.HasValue && entry.Value.longitude.HasValue) { if (!(Between(entry.Value.latitude.Value, map.NorthEastCorner.Latitude, map.SouthWestCorner.Latitude) && Between(entry.Value.longitude.Value, map.NorthEastCorner.Longitude, map.SouthWestCorner.Longitude))) { _log.Trace($"{SourceID} - Ignoring raid {entry.Key} @{entry.Value.raid_battle} based on location, it's outside my area of interest."); continue; } } _log.Trace($"{SourceID} - Incoming raid {entry.Key} @{entry.Value.raid_battle} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); DateTimeOffset raidStartTime = entry.Value.raid_battle.HasValue ? DateTimeOffset.FromUnixTimeSeconds(entry.Value.raid_battle ?? 0) : DateTimeOffset.MinValue; DateTimeOffset raidEndTime = entry.Value.raid_end.HasValue ? DateTimeOffset.FromUnixTimeSeconds(entry.Value.raid_end ?? 0) : DateTimeOffset.MinValue; // Look for this exact raid var raidStruct = raidsList.Where(x => (x.Raid.Sources != null) && (x.Raid.Sources.Where(s => s.SourceID == SourceID && s.ExternalID == entry.Key).Any())).FirstOrDefault(); if (null != raidStruct) { _log.Trace($"Found existing raid with same external ID: pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url} === id: {raidStruct.PublicID} / {raidStruct.Raid.Raid} / {raidStruct.Raid.Gym}"); } // search for a PUBLISHED raid that's similar in location and time if (null == raidStruct) { raidStruct = raidsList.Where(rp => { if (rp.Raid != null && rp.Raid.Location != null && raidEndTime != null && rp.Raid.RaidEndTime != null) { var loc1 = new GeoCoordinate(rp.Raid.Location.Latitude, rp.Raid.Location.Longitude); var loc2 = new GeoCoordinate(entry.Value.latitude ?? 0, entry.Value.longitude ?? 0); var distance = loc1.GetDistanceTo(loc2); return((distance <= 50) && (Math.Abs((raidEndTime.UtcDateTime - rp.Raid.RaidEndTime).TotalSeconds) <= 300) && rp.IsPublished); } else { return(false); } }).FirstOrDefault(); if (null != raidStruct) { _log.Trace($"Merging raid pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url} with existing raid id: {raidStruct.PublicID} / {raidStruct.Raid.Raid} / {raidStruct.Raid.Gym}"); } } string currentValues; // Create a new raid if (null == raidStruct) { _log.Trace($"{SourceID} - Adding new raid {entry.Key} @{entry.Value.raid_battle} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); raidStruct = new RaidParticipation { Raid = new RaidDescription { Alignment = Team.Unknown, Sources = new List <ExternalSource>() { new ExternalSource { ExternalID = entry.Key, SourceID = SourceID, URL = entry.Value.url } }, User = new Botje.Messaging.Models.User { IsBot = true, ID = -1, FirstName = SourceID, LastName = SourceID, Username = SourceID }, UpdateCount = 1, } }; raidParticipationCollection.Insert(raidStruct); currentValues = ""; } else { currentValues = raidStruct.AllValuesAsString(); } // update raidStruct if (entry.Value.raid_pokemon_id != null) { var pokedexEntry = Pokedex.All.Where(x => x.id == entry.Value.raid_pokemon_id).FirstOrDefault(); if (null == pokedexEntry) { raidStruct.Raid.Raid = $"Pokémon {entry.Value.raid_pokemon_id} (level {entry.Value.raid_level})"; } else { raidStruct.Raid.Raid = $"{pokedexEntry.name} (level {entry.Value.raid_level})"; } } else { raidStruct.Raid.Raid = $"Level {entry.Value.raid_level} raid"; } if (raidStruct.Raid.RaidUnlockTime != raidStartTime.UtcDateTime) { raidStruct.Raid.RaidUnlockTime = raidStartTime.UtcDateTime; } if (raidStruct.Raid.RaidEndTime != raidEndTime.UtcDateTime) { raidStruct.Raid.RaidEndTime = raidEndTime.UtcDateTime; } if (raidStruct.Raid.Gym != entry.Value.name) { raidStruct.Raid.Gym = entry.Value.name; } if (entry.Value.ex_trigger && string.IsNullOrEmpty(raidStruct.Raid.Remarks)) { raidStruct.Raid.Remarks = $"EX Raid Trigger"; } if (raidStruct.Raid.Publications == null) { raidStruct.Raid.Publications = new List <PublicationEntry>(); } if (entry.Value.longitude.HasValue && entry.Value.latitude.HasValue && (null == raidStruct.Raid.Location || raidStruct.Raid.Location.Latitude != entry.Value.latitude.Value || raidStruct.Raid.Location.Longitude != entry.Value.longitude.Value)) { raidStruct.Raid.Location = new Location { Latitude = entry.Value.latitude.Value, Longitude = entry.Value.longitude.Value }; } if (string.IsNullOrEmpty(raidStruct.Raid.Address)) { UpdateAddress(raidParticipationCollection, raidStruct, raidStruct.Raid.Location); } var newValues = raidStruct.AllValuesAsString(); if (newValues != currentValues) { if (!raidStruct.Raid.Publications.Where(x => x.ChannelID == channel).Any()) { _log.Trace($"{SourceID} - Publishing {entry.Key} @{entry.Value.raid_battle} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); var message = RaidEventHandler.ShareRaidToChat(raidStruct, channel); if (channel == Settings.PublicationChannel) { raidStruct.Raid.TelegramMessageID = message?.MessageID; raidStruct.IsPublished = true; } raidStruct.Raid.Publications.Add(new PublicationEntry { ChannelID = channel, TelegramMessageID = message?.MessageID ?? long.MaxValue }); } raidStruct.LastModificationTime = DateTime.UtcNow; raidParticipationCollection.Update(raidStruct); } else { _log.Trace($"Nothing changed for raid {raidStruct.PublicID}, not updating anything."); } } }
private void CreateRaidsFromScanResult(PogoAfoMapping map, PogoAfoResult pogoAfoResult, long channel) { var raidParticipationCollection = DB.GetCollection <RaidParticipation>(); var raidsList = raidParticipationCollection.Find(x => x.Raid.RaidEndTime >= DateTime.UtcNow).ToArray(); foreach (var entry in pogoAfoResult.raids ?? new Dictionary <string, PogoAfoRaidInfo>()) { _log.Trace($"{SourceID} - Incoming raid {entry.Key} @{entry.Value.raid_battle} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); DateTimeOffset raidStartTime = entry.Value.raid_battle.HasValue ? DateTimeOffset.FromUnixTimeSeconds(entry.Value.raid_battle ?? 0) : DateTimeOffset.MinValue; DateTimeOffset raidEndTime = entry.Value.raid_end.HasValue ? DateTimeOffset.FromUnixTimeSeconds(entry.Value.raid_end ?? 0) : DateTimeOffset.MinValue; // Look for this exact raid var raidStruct = raidsList.Where(x => (x.Raid.Sources != null) && (x.Raid.Sources.Where(s => s.SourceID == SourceID && s.ExternalID == entry.Key).Any())).FirstOrDefault(); if (null != raidStruct) { _log.Trace($"Found existing raid with same external ID: pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url} === id: {raidStruct.PublicID} / {raidStruct.Raid.Raid} / {raidStruct.Raid.Gym}"); } // search for a PUBLISHED raid that's similar in location and time if (null == raidStruct) { raidStruct = raidsList.Where(rp => { if (rp.Raid != null && rp.Raid.Location != null && raidEndTime != null && rp.Raid.RaidEndTime != null) { var loc1 = new GeoCoordinate(rp.Raid.Location.Latitude, rp.Raid.Location.Longitude); var loc2 = new GeoCoordinate(entry.Value.latitude ?? 0, entry.Value.longitude ?? 0); var distance = loc1.GetDistanceTo(loc2); return((distance <= 50) && (Math.Abs((raidEndTime.UtcDateTime - rp.Raid.RaidEndTime).TotalSeconds) <= 300) && rp.IsPublished); } else { return(false); } }).FirstOrDefault(); if (null != raidStruct) { _log.Trace($"Merging raid pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url} with existing raid id: {raidStruct.PublicID} / {raidStruct.Raid.Raid} / {raidStruct.Raid.Gym}"); } } string currentValues; // Create a new raid if (null == raidStruct) { _log.Trace($"{SourceID} - Adding new raid {entry.Key} @{entry.Value.raid_battle} / pokémon: {entry.Value.raid_pokemon_id} / gym: {entry.Value.name} / url: {entry.Value.url}"); raidStruct = new RaidParticipation { Raid = new RaidDescription { Alignment = Team.Unknown, Sources = new List <ExternalSource>() { new ExternalSource { ExternalID = entry.Key, SourceID = SourceID, URL = entry.Value.url } }, User = new Botje.Messaging.Models.User { IsBot = true, ID = -1, FirstName = SourceID, LastName = SourceID, Username = SourceID }, UpdateCount = 1, } }; raidParticipationCollection.Insert(raidStruct); currentValues = ""; } else { currentValues = raidStruct.AllValuesAsString(); } // update raidStruct if (entry.Value.raid_pokemon_id != null) { var pokedexEntry = Pokedex.All.Where(x => x.id == entry.Value.raid_pokemon_id).FirstOrDefault(); if (null == pokedexEntry) { raidStruct.Raid.Raid = $"Pokémon {entry.Value.raid_pokemon_id} (level {entry.Value.raid_level})"; } else { raidStruct.Raid.Raid = $"{pokedexEntry.name} (level {entry.Value.raid_level})"; } } else { raidStruct.Raid.Raid = $"Level {entry.Value.raid_level} raid"; } if (raidStruct.Raid.RaidUnlockTime != raidStartTime.UtcDateTime) { raidStruct.Raid.RaidUnlockTime = raidStartTime.UtcDateTime; } if (raidStruct.Raid.RaidEndTime != raidEndTime.UtcDateTime) { raidStruct.Raid.RaidEndTime = raidEndTime.UtcDateTime; } if (raidStruct.Raid.Gym != entry.Value.name) { raidStruct.Raid.Gym = entry.Value.name; } if (entry.Value.ex_trigger && string.IsNullOrEmpty(raidStruct.Raid.Remarks)) { raidStruct.Raid.Remarks = $"EX Raid Trigger"; } if (entry.Value.longitude.HasValue && entry.Value.latitude.HasValue && (null == raidStruct.Raid.Location || raidStruct.Raid.Location.Latitude != entry.Value.latitude.Value || raidStruct.Raid.Location.Longitude != entry.Value.longitude.Value)) { raidStruct.Raid.Location = new Location { Latitude = entry.Value.latitude.Value, Longitude = entry.Value.longitude.Value }; } var newValues = raidStruct.AllValuesAsString(); if (newValues != currentValues) { // TODO: REWRITE THIS TO MARK THE MESSAGE FOR PUBLICATION AND THE PUBLISH IT IN A SEPARATE LOOP PublishRaidToPrimaryChannelIfNeeded(channel, entry, raidStruct); if (null == raidStruct.Raid.Publications) { raidStruct.Raid.Publications = new List <PublicationEntry>(); } if (null != map.Targets && map.Targets.Count > 0) { CreatePublicationEntriesForAlternativeTargets(map.Targets, entry, raidStruct); } raidStruct.LastModificationTime = DateTime.UtcNow; raidParticipationCollection.Update(raidStruct); } else { _log.Trace($"Nothing changed for raid {raidStruct.PublicID}, not updating anything."); } if (string.IsNullOrEmpty(raidStruct.Raid.Address)) { UpdateAddress(raidParticipationCollection, raidStruct, raidStruct.Raid.Location); } } }