public static string GetRaidEggIcon(this RaidData raid, WhConfig whConfig, string style) { var iconStyleUrl = whConfig.IconStyles[style]; var url = iconStyleUrl.EndsWith('/') ? iconStyleUrl + "eggs" : $"{iconStyleUrl}/eggs"; return($"{url}/{raid.Level}.png"); }
private void ParseRaid(dynamic message) { try { RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message)); if (raid == null) { _logger.Error($"Failed to parse Pokemon webhook object: {message}"); return; } if (SkipEggs && raid.PokemonId == 0) { _logger.Debug($"Level {raid.Level} Egg, skipping..."); return; } raid.SetTimes(); OnRaidReceived(raid); } catch (Exception ex) { _logger.Error(ex.StackTrace); _logger.Debug(Convert.ToString(message)); } }
public EpgpRaidMonitor(IEmoteService emoteService, RaidData raidData, IServiceScopeFactory serviceScopeFactory) { _emoteService = emoteService; _raidData = raidData; _serviceScopeFactory = serviceScopeFactory; _cts = new CancellationTokenSource(); _raidData.RaidObject.PropertyChanged += RaidPropertyChanged; }
public ScannedRaid(RaidData raid) { Latitude = raid.Latitude; Longitude = raid.Longitude; Level = raid.Level; PokemonId = raid.PokemonId; FormId = raid.Form; CostumeId = raid.Costume; ExpireTime = raid.EndTime; }
private void ParseRaid(dynamic message) { try { RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message)); if (raid == null) { _logger.Error($"Failed to parse Pokemon webhook object: {message}"); return; } /* * if (SkipEggs && raid.PokemonId == 0) * { * _logger.Debug($"Level {raid.Level} Egg, skipping..."); * return; * } */ raid.SetTimes(); if (_checkForDuplicates) { lock (_processedRaids) { if (_processedRaids.ContainsKey(raid.GymId)) { if (_processedRaids[raid.GymId].PokemonId == raid.PokemonId && _processedRaids[raid.GymId].FormId == raid.Form && _processedRaids[raid.GymId].CostumeId == raid.Costume && _processedRaids[raid.GymId].Level == raid.Level && !_processedRaids[raid.GymId].IsExpired) { // Processed raid already return; } _processedRaids[raid.GymId] = new ScannedRaid(raid); } else { _processedRaids.Add(raid.GymId, new ScannedRaid(raid)); } } } OnRaidReceived(raid); } catch (Exception ex) { _logger.Error(ex.StackTrace); _logger.Debug(Convert.ToString(message)); } }
private void OnRaidSubscriptionTriggered(object sender, RaidData e) { if (_subProcessor == null) { return; } if (!ThreadPool.QueueUserWorkItem(async x => await _subProcessor.ProcessRaidSubscription(e))) { // Failed to queue thread _logger.Error($"Failed to queue thread to process raid subscription"); } }
private void ParseRaid(dynamic message) { try { RaidData raid = JsonConvert.DeserializeObject <RaidData>(Convert.ToString(message)); if (raid == null) { _logger.Error($"Failed to parse Pokemon webhook object: {message}"); return; } if (SkipEggs && raid.PokemonId == 0) { _logger.Debug($"Level {raid.Level} Egg, skipping..."); return; } raid.SetTimes(); lock (_processedRaids) { if (_processedRaids.ContainsKey(raid.GymId)) { /* * if ((_processedRaids[raid.GymId].PokemonId == 0 || _processedRaids[raid.GymId].PokemonId == raid.PokemonId) && * _processedRaids[raid.GymId].Form == raid.Form && * _processedRaids[raid.GymId].Level == raid.Level && * _processedRaids[raid.GymId].Start == raid.Start && * _processedRaids[raid.GymId].End == raid.End) * { * _logger.Debug($"PROCESSED RAID ALREADY: Id: {raid.GymId} Name: {raid.GymName} Pokemon: {raid.PokemonId} Form: {raid.Form} Start: {raid.StartTime} End: {raid.EndTime}"); * // Processed raid already * return; * } */ } else { _processedRaids.Add(raid.GymId, raid); } } OnRaidReceived(raid); } catch (Exception ex) { _logger.Error(ex.StackTrace); _logger.Debug(Convert.ToString(message)); } }
private void OnRaidSubscriptionTriggered(object sender, RaidData e) { if (!_whConfig.Discord.EnableSubscriptions) { return; } if (_subProcessor == null) { return; } new System.Threading.Thread(async() => await _subProcessor.ProcessRaidSubscription(e)) { IsBackground = true }.Start(); }
public async Task ProcessRaid(RaidData raid) { if (raid == null) { return; } if (_db == null) { _logger.Error($"Database is not initialized..."); return; } DiscordUser discordUser; Subscription <Pokemon> user; Pokemon subscribedRaid; DiscordEmbed embed; for (int i = 0; i < _db.Subscriptions.Count; i++) { try { user = _db.Subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } discordUser = await _client.GetUser(user.UserId); if (discordUser == null) { if (!_db.Subscriptions.Remove(user)) { _logger.Error($"Failed to remove non-existing user {user.UserId} from database."); } continue; } if (!user.Raids.Exists(x => x.PokemonId == raid.PokemonId)) { continue; } subscribedRaid = user.Raids.Find(x => x.PokemonId == raid.PokemonId); if (subscribedRaid == null) { continue; } //if (!_db.Pokemon.ContainsKey(subscribedRaid.PokemonId.ToString())) continue; //var pokemon = _db.Pokemon[subscribedRaid.PokemonId.ToString()]; //if (pokemon == null) continue; if (_client == null) { continue; } //if (!await _client.IsSupporterOrHigher(user.UserId, _config)) continue; if (subscribedRaid.PokemonId != raid.PokemonId) { continue; } if (user.NotificationLimiter.IsLimited()) { if (!user.NotifiedOfLimited) { await _client.SendDirectMessage(discordUser, string.Format(NotificationsLimitedMessage, NotificationLimiter.MaxNotificationsPerMinute), null); user.NotifiedOfLimited = true; } continue; } user.NotifiedOfLimited = false; _logger.Info($"Notifying user {discordUser.Username} that a {raid.PokemonId} raid is available..."); embed = await _builder.BuildRaidMessage(raid, user.UserId); if (embed == null) { continue; } //if (await CheckIfExceededNotificationLimit(user)) return; user.NotificationsToday++; await SendNotification(discordUser, raid.PokemonId.ToString(), embed); } catch (Exception ex) { _logger.Error(ex); } } }
public void AddOrUpdateRaid(RaidData raidData) { _raids.AddOrUpdate(raidData.Id, id => raidData, (id, data) => raidData); }
public EpgpRaidMonitor GetNew(RaidData raidData) { return(new EpgpRaidMonitor(_emoteService, raidData, _serviceScopeFactory)); }
public async Task ProcessRaidSubscription(RaidData raid) { if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId)) { return; } var loc = _whm.GetGeofence(raid.Latitude, raid.Longitude); if (loc == null) { //_logger.Warn($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping..."); return; } var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form); for (int i = 0; i < subscriptions.Count; i++) { try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } if (!_whConfig.Servers.ContainsKey(user.GuildId)) { continue; } if (!_whConfig.Servers[user.GuildId].EnableSubscriptions) { continue; } if (!_servers.ContainsKey(user.GuildId)) { continue; } var client = _servers[user.GuildId]; var member = await client.GetMemberById(user.GuildId, user.UserId); if (member == null) { _logger.Warn($"Failed to find member with id {user.UserId}."); continue; } if (!member.HasSupporterRole(_whConfig.Servers[user.GuildId].DonorRoleIds)) { _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name}..."); continue; } // Only check distance if user has it set if (user.DistanceM > 0) { var distance = new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(raid.Latitude, raid.Longitude)); if (user.DistanceM < distance) { //Skip if distance is set and is not met. _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is farther than set distance of '{user.DistanceM} meters."); continue; } } if (user.Gyms.Count > 0 && (!user.Gyms?.Exists(x => !string.IsNullOrEmpty(x?.Name) && ( (raid.GymName?.ToLower()?.Contains(x.Name?.ToLower()) ?? false) || (raid.GymName?.ToLower()?.StartsWith(x.Name?.ToLower()) ?? false) ) ) ?? false)) { //Skip if list is not empty and gym is not in list. _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid '{raid.GymName}' is not in list of subscribed gyms."); continue; } var form = Translator.Instance.GetFormName(raid.Form); var exists = user.Raids.FirstOrDefault(x => x.PokemonId == raid.PokemonId && (string.IsNullOrEmpty(x.Form) || string.Compare(x.Form, form, true) == 0) && (string.IsNullOrEmpty(x.City) || (!string.IsNullOrEmpty(x.City) && string.Compare(loc.Name, x.City, true) == 0)) ) != null; if (!exists) { //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'."); continue; } var embed = raid.GenerateRaidMessage(user.GuildId, client, _whConfig, null, loc.Name); foreach (var emb in embed.Embeds) { _queue.Enqueue(new NotificationItem(user, member, emb, pokemon.Name, loc.Name)); } Statistics.Instance.SubscriptionRaidsSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; user = null; loc = null; await Task.CompletedTask; }
public async Task ProcessGymSubscription(RaidData raid) { //if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId)) // return; // Cache the result per-guild so that geospatial stuff isn't queried for every single subscription below Dictionary <ulong, GeofenceItem> locationCache = new Dictionary <ulong, GeofenceItem>(); GeofenceItem GetGeofence(ulong guildId) { if (!locationCache.TryGetValue(guildId, out var geofence)) { geofence = _whm.GetGeofence(guildId, raid.Latitude, raid.Longitude); locationCache.Add(guildId, geofence); } return(geofence); } var subscriptions = Manager.GetUserSubscriptionsByGymName(raid.GymName); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form); for (int i = 0; i < subscriptions.Count; i++) { //var start = DateTime.Now; try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } if (!_whConfig.Instance.Servers.ContainsKey(user.GuildId)) { continue; } if (!_whConfig.Instance.Servers[user.GuildId].Subscriptions.Enabled) { continue; } if (!_servers.ContainsKey(user.GuildId)) { continue; } var client = _servers[user.GuildId]; var member = await client.GetMemberById(user.GuildId, user.UserId); if (member == null) { _logger.Warn($"Failed to find member with id {user.UserId}."); continue; } if (!member.HasSupporterRole(_whConfig.Instance.Servers[user.GuildId].DonorRoleIds)) { _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name} for gym {raid.GymName}..."); // Automatically disable users subscriptions if not supporter to prevent issues //user.Enabled = false; //user.Save(false); continue; } var geofence = GetGeofence(user.GuildId); if (geofence == null) { //_logger.Warn($"Failed to lookup city from coordinates {pkmn.Latitude},{pkmn.Longitude} {db.Pokemon[pkmn.Id].Name} {pkmn.IV}, skipping..."); continue; } var gymSub = user.Gyms.FirstOrDefault(x => string.Compare(x.Name, raid.GymName, true) == 0); if (gymSub == null) { continue; } var checkLevel = gymSub.MinimumLevel > 0 && gymSub.MaximumLevel > 0; var containsPokemon = gymSub.PokemonIDs?.Contains((uint)raid.PokemonId) ?? false; if (!checkLevel && !containsPokemon) { continue; } var embed = raid.GenerateRaidMessage(user.GuildId, client, _whConfig.Instance, null, geofence.Name); //var end = DateTime.Now; //_logger.Debug($"Took {end} to process gym raid subscription for user {user.UserId}"); embed.Embeds.ForEach(x => _queue.Enqueue(new NotificationItem(user, member, x, pokemon.Name, geofence.Name))); Statistics.Instance.SubscriptionRaidsSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; user = null; await Task.CompletedTask; }
public async Task ProcessRaidSubscription(RaidData raid) { if (!_whConfig.Discord.EnableSubscriptions) { return; } var db = Database.Instance; if (!db.Pokemon.ContainsKey(raid.PokemonId)) { return; } var loc = _whm.GetGeofence(raid.Latitude, raid.Longitude); if (loc == null) { //_logger.Warn($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping..."); return; } var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; var pokemon = db.Pokemon[raid.PokemonId]; for (int i = 0; i < subscriptions.Count; i++) { try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } var member = await _client.GetMemberById(_whConfig.Discord.GuildId, user.UserId); if (member == null) { _logger.Warn($"Failed to find member with id {user.UserId}."); continue; } if (!member.HasSupporterRole(_whConfig.Discord.DonorRoleIds)) { _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name}..."); continue; } //if (!member.Roles.Select(x => x.Name.ToLower()).Contains(loc.Name.ToLower())) //{ // _logger.Debug($"[{loc.Name}] Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name} because they do not have the city role '{loc.Name}'."); // continue; //} if (user.DistanceM > 0) { var distance = new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(raid.Latitude, raid.Longitude)); if (user.DistanceM < distance) { //Skip if distance is set and is not met. _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is farther than set distance of '{user.DistanceM} meters."); continue; } } if (user.Gyms.Count > 0 && !user.Gyms.Exists(x => !string.IsNullOrEmpty(x?.Name) && raid.GymName.ToLower().Contains(x.Name?.ToLower()))) { //Skip if list is not empty and gym is not in list. _logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid '{raid.GymName}' is not in list of subscribed gyms."); continue; } var form = raid.PokemonId.GetPokemonForm(raid.Form.ToString()); var exists = user.Raids.FirstOrDefault(x => x.PokemonId == raid.PokemonId && //(string.Compare(x.Form, form, true) == 0 || string.IsNullOrEmpty(x.Form)) && (x.Form == null || x.Form == string.Empty || string.Compare(x.Form, form, true) == 0) && //string.Compare(x.Form, form, true) == 0 && (string.IsNullOrEmpty(x.City) || (!string.IsNullOrEmpty(x.City) && string.Compare(loc.Name, x.City, true) == 0)) ) != null; if (!exists) { //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'."); continue; } //_logger.Debug($"Notifying user {member.Username} that a {raid.PokemonId} raid is available..."); var iconStyle = Manager.GetUserIconStyle(user); var embed = raid.GenerateRaidMessage(_client, _whConfig, null, loc.Name, string.Format(_whConfig.IconStyles[iconStyle], raid.PokemonId, raid.Form)); _queue.Enqueue(new Tuple <DiscordUser, string, DiscordEmbed>(member, pokemon.Name, embed)); //if (!Manager.AddRaidStatistic(member.Id, raid)) //{ // _logger.Warn($"Failed to add {pokemon.Name} raid statistic for user {user.Id}."); //} Statistics.Instance.SubscriptionRaidsSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; user = null; loc = null; db = null; await Task.CompletedTask; }
private void ProcessRaid(RaidData raid) { if (raid == null) { return; } if (raid.IsEgg) { Statistics.Instance.TotalReceivedEggs++; } else { Statistics.Instance.TotalReceivedRaids++; } foreach (var(guildId, alarms) in _alarms) { if (!alarms.EnableRaids) { continue; } if (alarms.Alarms?.Count == 0) { continue; } var raidAlarms = alarms.Alarms.FindAll(x => x.Filters?.Raids?.Pokemon != null); for (var j = 0; j < raidAlarms.Count; j++) { var alarm = raidAlarms[j]; var geofence = GeofenceService.GetGeofence(alarm.GeofenceItems, new Location(raid.Latitude, raid.Longitude)); if (geofence == null) { //_logger.Info($"[{alarm.Name}] Skipping raid Pokemon={raid.PokemonId}, Level={raid.Level}: not in geofence."); continue; } if (raid.IsEgg) { if (alarm.Filters.Eggs == null) { continue; } if (!alarm.Filters.Eggs.Enabled) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: raids filter not enabled."); continue; } if (!int.TryParse(raid.Level, out var level)) { _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level."); continue; } if (!(level >= alarm.Filters.Eggs.MinimumLevel && level <= alarm.Filters.Eggs.MaximumLevel)) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Eggs.MinimumLevel} and MaximumLevel={alarm.Filters.Eggs.MaximumLevel} filters."); continue; } if (alarm.Filters.Eggs.OnlyEx && !raid.IsExEligible) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: only ex {alarm.Filters.Eggs.OnlyEx}."); continue; } if (alarm.Filters.Eggs.Team != PokemonTeam.All && alarm.Filters.Eggs.Team != raid.Team) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Team}' does not meet Team={alarm.Filters.Eggs.Team} filter."); continue; } OnRaidAlarmTriggered(raid, alarm, guildId); } else { if (alarm.Filters.Raids == null) { continue; } if (!alarm.Filters.Raids.Enabled) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: raids filter not enabled."); continue; } if (!int.TryParse(raid.Level, out var level)) { _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level."); continue; } if (!(level >= alarm.Filters.Raids.MinimumLevel && level <= alarm.Filters.Raids.MaximumLevel)) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid {raid.PokemonId}: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Raids.MinimumLevel} and MaximumLevel={alarm.Filters.Raids.MaximumLevel} filters."); continue; } if (alarm.Filters.Raids.FilterType == FilterType.Exclude && alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId)) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}."); continue; } if (alarm.Filters.Raids.FilterType == FilterType.Include && (!alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId) && alarm.Filters.Raids.Pokemon?.Count > 0)) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}."); continue; } if (alarm.Filters.Raids.OnlyEx && !raid.IsExEligible) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: only ex {alarm.Filters.Raids.OnlyEx}."); continue; } if (alarm.Filters.Raids.Team != PokemonTeam.All && alarm.Filters.Raids.Team != raid.Team) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: '{raid.Team}' does not meet Team={alarm.Filters.Raids.Team} filter."); continue; } if (alarm.Filters.Raids.IgnoreMissing && raid.IsMissingStats) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: IgnoreMissing=true."); continue; } OnRaidAlarmTriggered(raid, alarm, guildId); } } } }
private void ProcessRaid(RaidData raid) { if (!_alarms.EnableRaids) { return; } if (raid == null) { return; } if (_alarms.Alarms?.Count == 0) { return; } for (var i = 0; i < _alarms.Alarms.Count; i++) { var alarm = _alarms.Alarms[i]; var geofence = InGeofence(alarm.Geofences, new Location(raid.Latitude, raid.Longitude)); if (geofence == null) { //_logger.Info($"[{alarm.Name}] Skipping raid Pokemon={raid.PokemonId}, Level={raid.Level} because not in geofence."); continue; } if (raid.IsEgg) { if (alarm.Filters.Eggs == null) { continue; } if (!alarm.Filters.Eggs.Enabled) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: raids filter not enabled."); continue; } if (!int.TryParse(raid.Level, out var level)) { _logger.Warn($"[{alarm.Name}] [{geofence.Name}] Failed to parse '{raid.Level}' as raid level."); continue; } if (!(level >= alarm.Filters.Eggs.MinimumLevel && level <= alarm.Filters.Eggs.MaximumLevel)) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Level}' does not meet the MinimumLevel={alarm.Filters.Eggs.MinimumLevel} and MaximumLevel={alarm.Filters.Eggs.MaximumLevel} filters."); continue; } if (alarm.Filters.Eggs.OnlyEx && !raid.IsExEligible) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: only ex {alarm.Filters.Eggs.OnlyEx}."); continue; } if (alarm.Filters.Eggs.Team != PokemonTeam.All && alarm.Filters.Eggs.Team != raid.Team) { //_logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping level {raid.Level} raid egg: '{raid.Team}' does not meet Team={alarm.Filters.Eggs.Team} filter."); continue; } OnRaidAlarmTriggered(raid, alarm); } else { if (alarm.Filters.Raids == null) { continue; } if (!alarm.Filters.Raids.Enabled) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: raids filter not enabled."); continue; } if (alarm.Filters.Raids.FilterType == FilterType.Exclude && alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId)) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}."); continue; } if (alarm.Filters.Raids.FilterType == FilterType.Include && (!alarm.Filters.Raids.Pokemon.Contains(raid.PokemonId) && alarm.Filters.Raids.Pokemon?.Count > 0)) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: filter {alarm.Filters.Raids.FilterType}."); continue; } if (alarm.Filters.Raids.OnlyEx && !raid.IsExEligible) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: only ex {alarm.Filters.Raids.OnlyEx}."); continue; } if (alarm.Filters.Raids.Team != PokemonTeam.All && alarm.Filters.Raids.Team != raid.Team) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: '{raid.Team}' does not meet Team={alarm.Filters.Raids.Team} filter."); continue; } if (alarm.Filters.Raids.IgnoreMissing && raid.IsMissingStats) { _logger.Info($"[{alarm.Name}] [{geofence.Name}] Skipping raid boss {raid.PokemonId}: IgnoreMissing=true."); continue; } OnRaidAlarmTriggered(raid, alarm); } } }
public RaidDataEventArgs(RaidData raid) { Raid = raid; }
public void Dispose() { _raidData.RaidObject.PropertyChanged -= RaidPropertyChanged; _cts?.Dispose(); _raidData = null; }
private void OnRaidReceived(RaidData raid) => RaidReceived?.Invoke(this, new DataReceivedEventArgs <RaidData>(raid));
public async Task <DiscordEmbed> BuildRaidMessage(RaidData raid, ulong userId) { var pkmn = _db.Pokemon[raid.PokemonId.ToString()]; if (pkmn == null) { _logger.Error($"Failed to lookup Raid Pokemon '{raid.PokemonId}' in database."); return(null); } var user = await _client.GetMemberFromUserId(userId); if (user == null) { _logger.Error($"Failed to get discord member object from user id {userId}."); return(null); } //var loc = Utils.GetGoogleAddress(raid.Latitude, raid.Longitude, _config.GmapsKey); var loc = _geofenceSvc.GetGeofence(new Location(raid.Latitude, raid.Longitude)); if (loc == null) { _logger.Error($"Failed to lookup city for coordinates {raid.Latitude},{raid.Longitude}, skipping..."); return(null); } if (!_config.CityRoles.Exists(x => string.Compare(x, loc.Name, true) == 0)) { File.AppendAllText("cities.txt", $"City: {loc.Name}\r\n"); } if (!_client.HasRole(user, loc.Name)) { _logger.Debug($"Skipping notification for user {user.DisplayName} ({user.Id}) for Pokemon {pkmn.Name} because they do not have the city role '{loc.Name}'."); return(null); } var eb = new DiscordEmbedBuilder { Title = loc == null || string.IsNullOrEmpty(loc.Name) ? "DIRECTIONS" : loc.Name, //Description = $"{pkmn.Name} raid available until {raid.EndTime.ToLongTimeString()}!", Url = string.Format(Strings.GoogleMaps, raid.Latitude, raid.Longitude), ImageUrl = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude), ThumbnailUrl = string.Format(Strings.PokemonImage, raid.PokemonId, 0), Color = DiscordHelpers.BuildRaidColor(Convert.ToInt32(raid.Level)) }; var fixedEndTime = DateTime.Parse(raid.EndTime.ToLongTimeString()); var remaining = GetTimeRemaining(fixedEndTime); eb.Description = $"{pkmn.Name} Raid Ends: {raid.EndTime.ToLongTimeString()}\r\n\r\n"; eb.Description += $"**Starts:** {raid.StartTime.ToLongTimeString()}\r\n"; eb.Description += $"**Ends:** {raid.EndTime.ToLongTimeString()} ({remaining.ToReadableStringNoSeconds()} left)\r\n"; var perfectRange = _db.GetPokemonCpRange(raid.PokemonId, 20); var boostedRange = _db.GetPokemonCpRange(raid.PokemonId, 25); eb.Description += $"**Perfect CP:** {perfectRange.Best} / :white_sun_rain_cloud: {boostedRange.Best}\r\n"; if (pkmn.Types.Count > 0) { var types = new List <string>(); pkmn.Types.ForEach(x => { if (Strings.TypeEmojis.ContainsKey(x.Type.ToLower())) { types.Add(Strings.TypeEmojis[x.Type.ToLower()] + " " + x.Type); } }); eb.Description += $"**Types:** {string.Join("/", types)}\r\n"; } var fastMove = _db.Movesets.ContainsKey(raid.FastMove) ? _db.Movesets[raid.FastMove] : null; if (fastMove != null) { eb.Description += $"**Fast Move:** {Strings.TypeEmojis[fastMove.Type.ToLower()]} {fastMove.Name}\r\n"; } var chargeMove = _db.Movesets.ContainsKey(raid.ChargeMove) ? _db.Movesets[raid.ChargeMove] : null; if (chargeMove != null) { eb.Description += $"**Charge Move:** {Strings.TypeEmojis[chargeMove.Type.ToLower()]} {chargeMove.Name}\r\n"; } var strengths = new List <string>(); var weaknesses = new List <string>(); foreach (var type in pkmn.Types) { foreach (var strength in PokemonExtensions.GetStrengths(type.Type)) { if (!strengths.Contains(strength)) { strengths.Add(strength); } } foreach (var weakness in PokemonExtensions.GetWeaknesses(type.Type)) { if (!weaknesses.Contains(weakness)) { weaknesses.Add(weakness); } } } if (strengths.Count > 0) { eb.Description += $"**Strong Against:** {string.Join(", ", strengths)}\r\n"; } if (weaknesses.Count > 0) { eb.Description += $"**Weaknesses:** {string.Join(", ", weaknesses)}\r\n"; } eb.Description += $"**Location:** {Math.Round(raid.Latitude, 5)},{Math.Round(raid.Longitude, 5)}"; eb.ImageUrl = string.Format(Strings.GoogleMapsStaticImage, raid.Latitude, raid.Longitude) + $"&key={_config.GmapsKey}"; eb.Footer = new DiscordEmbedBuilder.EmbedFooter { Text = $"versx | {DateTime.Now}" }; var embed = eb.Build(); return(embed); }
private void OnRaidSubscriptionTriggered(RaidData raid) { RaidSubscriptionTriggered?.Invoke(this, raid); }
public async Task ProcessRaidSubscription(RaidData raid) { if (!MasterFile.Instance.Pokedex.ContainsKey(raid.PokemonId)) { return; } // Cache the result per-guild so that geospatial stuff isn't queried for every single subscription below Dictionary <ulong, GeofenceItem> locationCache = new Dictionary <ulong, GeofenceItem>(); GeofenceItem GetGeofence(ulong guildId) { if (!locationCache.TryGetValue(guildId, out var geofence)) { geofence = _whm.GetGeofence(guildId, raid.Latitude, raid.Longitude); locationCache.Add(guildId, geofence); } return(geofence); } var subscriptions = Manager.GetUserSubscriptionsByRaidBossId(raid.PokemonId); if (subscriptions == null) { _logger.Warn($"Failed to get subscriptions from database table."); return; } SubscriptionObject user; var pokemon = MasterFile.GetPokemon(raid.PokemonId, raid.Form); for (int i = 0; i < subscriptions.Count; i++) { //var start = DateTime.Now; try { user = subscriptions[i]; if (user == null) { continue; } if (!user.Enabled) { continue; } if (!_whConfig.Instance.Servers.ContainsKey(user.GuildId)) { continue; } if (!_whConfig.Instance.Servers[user.GuildId].Subscriptions.Enabled) { continue; } if (!_servers.ContainsKey(user.GuildId)) { continue; } var client = _servers[user.GuildId]; var member = await client.GetMemberById(user.GuildId, user.UserId); if (member == null) { _logger.Warn($"Failed to find member with id {user.UserId}."); continue; } if (!member.HasSupporterRole(_whConfig.Instance.Servers[user.GuildId].DonorRoleIds)) { _logger.Info($"User {user.UserId} is not a supporter, skipping raid boss {pokemon.Name}..."); // Automatically disable users subscriptions if not supporter to prevent issues //user.Enabled = false; //user.Save(false); continue; } var form = Translator.Instance.GetFormName(raid.Form); var subPkmn = user.Raids.FirstOrDefault(x => x.PokemonId == raid.PokemonId && (string.IsNullOrEmpty(x.Form) || (!string.IsNullOrEmpty(x.Form) && string.Compare(x.Form, form, true) == 0)) ); // Not subscribed to Pokemon if (subPkmn == null) { //_logger.Debug($"Skipping notification for user {member.DisplayName} ({member.Id}) for raid boss {pokemon.Name}, raid is in city '{loc.Name}'."); continue; } var geofence = GetGeofence(user.GuildId); if (geofence == null) { //_logger.Warn($"Failed to lookup city from coordinates {pkmn.Latitude},{pkmn.Longitude} {db.Pokemon[pkmn.Id].Name} {pkmn.IV}, skipping..."); continue; } var distanceMatches = user.DistanceM > 0 && user.DistanceM > new Coordinates(user.Latitude, user.Longitude).DistanceTo(new Coordinates(raid.Latitude, raid.Longitude)); var geofenceMatches = subPkmn.Areas.Select(x => x.ToLower()).Contains(geofence.Name.ToLower()); // If set distance does not match and no geofences match, then skip Pokemon... if (!distanceMatches && !geofenceMatches) { continue; } var embed = raid.GenerateRaidMessage(user.GuildId, client, _whConfig.Instance, null, geofence.Name); //var end = DateTime.Now; //_logger.Debug($"Took {end} to process raid subscription for user {user.UserId}"); embed.Embeds.ForEach(x => _queue.Enqueue(new NotificationItem(user, member, x, pokemon.Name, geofence.Name))); Statistics.Instance.SubscriptionRaidsSent++; Thread.Sleep(5); } catch (Exception ex) { _logger.Error(ex); } } subscriptions.Clear(); subscriptions = null; user = null; await Task.CompletedTask; }
private void OnRaidAlarmTriggered(RaidData raid, AlarmObject alarm, ulong guildId) { RaidAlarmTriggered?.Invoke(this, new AlarmEventTriggeredEventArgs <RaidData>(raid, alarm, guildId)); }
public static async Task Initialize() => await Task.Run(() => { DiscordShardedClient client = ConfigProperties.Client; client.UserJoined += async u => { SocketGuild guild = u.Guild; Server server = await DatabaseQueries.GetOrCreateServerAsync(guild.Id); if (server.AntiRaid == null) { return; } AntiRaidConfig ar = server.AntiRaid; if (!ActiveAntiraids.Raids.Any(x => x.ServerId == server.ServerId)) { var newRaidData = new RaidData { ServerId = server.ServerId, UserIds = new HashSet <ulong> { u.Id } }; ActiveAntiraids.SafeAdd(newRaidData); } else { var newIds = new HashSet <ulong>(); HashSet <ulong> existingIds = ActiveAntiraids.Raids.First(x => x.ServerId == server.ServerId).UserIds; // Copies existing IDs from the known / active raid into a new HashSet<ulong>. foreach (ulong id in existingIds) { newIds.Add(id); } // Finally, add the current user's ID to the HashSet. newIds.Add(u.Id); // Replace the object in memory. ActiveAntiraids.ReplaceRaidData(new RaidData { ServerId = server.ServerId, UserIds = newIds }); } var timer = new Timer(ar.Seconds * 1000); timer.Enabled = true; timer.AutoReset = false; timer.Elapsed += async(sender, args) => { RaidData existingObj = ActiveAntiraids.Raids.FirstOrDefault(x => x.ServerId == server.ServerId); if (existingObj == null) { return; } // Filter by distinct to fix the duplicate users issue. existingObj.UserIds = existingObj.UserIds.Distinct().ToHashSet(); // This must be above ActionUsers() as it takes a few seconds for users to be actioned // resulting in duplicate log messages and ban attempts. ActiveAntiraids.RemoveAll(existingObj); if (existingObj.UserIds.Count >= ar.Users) { await ActionUsers(existingObj.UserIds, server.ServerId, ar.Action); } }; }; });